[img]
[/img]
嘎、换个图片吧 这张好看些 哈哈
[img]
[/img]
工程结构图:
[img]
[/img]
AsyncImageLoader:
package cn.anycall.testlist; import java.lang.ref.SoftReference; import java.util.HashMap; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.widget.ImageView; public class AsyncImageLoader { //SoftReference是软引用,是为了更好的为了系统回收变量 private static HashMap<String, SoftReference<Drawable>> imageCache; static { imageCache = new HashMap<String, SoftReference<Drawable>>(); } public AsyncImageLoader() { } public Drawable loadDrawable(final String imageUrl,final ImageView imageView, final ImageCallback imageCallback){ if (imageCache.containsKey(imageUrl)) { //从缓存中获取 SoftReference<Drawable> softReference = imageCache.get(imageUrl); Drawable drawable = softReference.get(); System.out.println("111111111111111111111111111111"); if (drawable != null) { System.out.println("11111111111122222222211111111111111111"); return drawable; } } final Handler handler = new Handler() { public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageView,imageUrl); } }; //建立新一个新的线程下载图片 new Thread() { @Override public void run() { System.out.println("11111111111133333333333211111111111111111"); Drawable drawable = null; try { drawable = ImageUtil.geRoundDrawableFromUrl(imageUrl, 20); } catch (Exception e) { e.printStackTrace(); } imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } }.start(); return null; } //回调接口 public interface ImageCallback { public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl); } }
ImageUtil
package cn.anycall.testlist; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; public class ImageUtil { public static InputStream getRequest(String path) throws Exception { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if (conn.getResponseCode() == 200){ return conn.getInputStream(); } return null; } public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outSteam.write(buffer, 0, len); } outSteam.close(); inStream.close(); return outSteam.toByteArray(); } public static Drawable loadImageFromUrl(String url){ URL m; InputStream i = null; try { m = new URL(url); i = (InputStream) m.getContent(); } catch (MalformedURLException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Drawable d = Drawable.createFromStream(i, "src"); return d; } public static Drawable getDrawableFromUrl(String url) throws Exception{ return Drawable.createFromStream(getRequest(url),null); } public static Bitmap getBitmapFromUrl(String url) throws Exception{ byte[] bytes = getBytesFromUrl(url); return byteToBitmap(bytes); } public static Bitmap getRoundBitmapFromUrl(String url,int pixels) throws Exception{ byte[] bytes = getBytesFromUrl(url); Bitmap bitmap = byteToBitmap(bytes); return toRoundCorner(bitmap, pixels); } public static Drawable geRoundDrawableFromUrl(String url,int pixels) throws Exception{ byte[] bytes = getBytesFromUrl(url); BitmapDrawable bitmapDrawable = (BitmapDrawable)byteToDrawable(bytes); return toRoundCorner(bitmapDrawable, pixels); } public static byte[] getBytesFromUrl(String url) throws Exception{ return readInputStream(getRequest(url)); } public static Bitmap byteToBitmap(byte[] byteArray){ if(byteArray.length!=0){ return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); } else { return null; } } public static Drawable byteToDrawable(byte[] byteArray){ ByteArrayInputStream ins = new ByteArrayInputStream(byteArray); return Drawable.createFromStream(ins, null); } public static byte[] Bitmap2Bytes(Bitmap bm){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitmap .createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; } /** * 图片去色,返回灰度图片 * @param bmpOriginal 传入的图片 * @return 去色后的图片 */ public static Bitmap toGrayscale(Bitmap bmpOriginal) { int width, height; height = bmpOriginal.getHeight(); width = bmpOriginal.getWidth(); Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); Canvas c = new Canvas(bmpGrayscale); Paint paint = new Paint(); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0); ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm); paint.setColorFilter(f); c.drawBitmap(bmpOriginal, 0, 0, paint); return bmpGrayscale; } /** * 去色同时加圆角 * @param bmpOriginal 原图 * @param pixels 圆角弧度 * @return 修改后的图片 */ public static Bitmap toGrayscale(Bitmap bmpOriginal, int pixels) { return toRoundCorner(toGrayscale(bmpOriginal), pixels); } /** * 把图片变成圆角 * @param bitmap 需要修改的图片 * @param pixels 圆角的弧度 * @return 圆角图片 */ public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * 使圆角功能支持BitampDrawable * @param bitmapDrawable * @param pixels * @return */ public static BitmapDrawable toRoundCorner(BitmapDrawable bitmapDrawable, int pixels) { Bitmap bitmap = bitmapDrawable.getBitmap(); bitmapDrawable = new BitmapDrawable(toRoundCorner(bitmap, pixels)); return bitmapDrawable; } }
TestListViewActivity
package cn.anycall.testlist; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.ListActivity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import cn.anycall.testlist.AsyncImageLoader.ImageCallback; public class TestListViewActivity extends ListActivity { private List<Map<String, Object>> mData = new ArrayList<Map<String, Object>>(); public final class ViewHolder { public ImageView img; public TextView title; public TextView info; } public List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>(); public int a = 0; public Button button; public LinearLayout layloading; public MyHandler myHandler; public MyAdapter adapter ; private AsyncImageLoader asyncImageLoader = new AsyncImageLoader(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myHandler = new MyHandler(); ListView listView = getListView();// 得到ListView LinearLayout listFooter = (LinearLayout) LayoutInflater.from(this) .inflate(R.layout.main_foot, null); listView.addFooterView(listFooter);// 添加FooterView button = (Button) findViewById(R.id.more); layloading = (LinearLayout) findViewById(R.id.loading); button.setVisibility(View.VISIBLE); layloading.setVisibility(View.GONE); adapter = new MyAdapter(this); setListAdapter(adapter); button.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { //起一个线程更新后台数据 MyThread m = new MyThread(); new Thread(m).start(); } }); for(int i=0;i<20;i++){ a++; Map<String, Object> map = new HashMap<String, Object>(); map.put("img", R.drawable.icon); map.put("title", "G"+a); map.put("info", "google"+a); mData.add(map); } } public class MyAdapter extends BaseAdapter { private LayoutInflater mInflater; public MyAdapter(Context context) { this.mInflater = LayoutInflater.from(context); } public int getCount() { return mData.size(); } public Object getItem(int arg0) { return null; } public long getItemId(int arg0) { return 0; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.main_list, null); holder.img = (ImageView)convertView.findViewById(R.id.img); holder.title = (TextView) convertView .findViewById(R.id.listtitle); holder.info = (TextView) convertView .findViewById(R.id.listtext); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //holder.img.setBackgroundResource((Integer)mData.get(position).get("img")); holder.title.setText((String) mData.get(position).get("title")); holder.info.setText((String) mData.get(position).get("info")); //异步加载图片 Drawable cachedImage = asyncImageLoader.loadDrawable("http://t02.pic.sogou.com/eb95234678ecb28d.jpg",holder.img, new ImageCallback(){ public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl) { imageView.setImageDrawable(imageDrawable); } }); System.out.println(cachedImage); if (cachedImage == null) { holder.img.setImageResource(R.drawable.icon); } else { holder.img.setImageDrawable(cachedImage); } return convertView; } } //更新后台数据 class MyThread implements Runnable { public void run() { String msglist = "1"; Message msg = new Message(); Bundle b = new Bundle();// 存放数据 b.putString("rmsg", msglist); msg.setData(b); TestListViewActivity.this.myHandler.sendMessage(msg); // 向Handler发送消息,更新UI try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } msglist = "2"; msg = new Message(); b = new Bundle();// 存放数据 b.putString("rmsg", msglist); msg.setData(b); TestListViewActivity.this.myHandler.sendMessage(msg); // 向Handler发送消息,更新UI } } class MyHandler extends Handler { public MyHandler() { } public MyHandler(Looper L) { super(L); } // 子类必须重写此方法,接受数据 @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); // 此处可以更新UI Bundle b = msg.getData(); String rmsg = b.getString("rmsg"); if ("1".equals(rmsg)) { // do nothing button.setVisibility(View.GONE); layloading.setVisibility(View.VISIBLE); }else if ("2".equals(rmsg)) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<20;i++){ a++; Map<String, Object> map = new HashMap<String, Object>(); map.put("img", R.drawable.icon); map.put("title", "G"+a); map.put("info", "google"+a); mData.add(map); } button.setVisibility(View.VISIBLE); layloading.setVisibility(View.GONE); adapter.notifyDataSetChanged(); } } } }
main_foot.xml
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:minHeight="?android:listPreferredItemHeight" xmlns:android="http://schemas.android.com/apk/res/android" android:background="#FFFFFF" > <Button android:textSize="16.0sp" android:textColor="#ff545454" android:gravity="center" android:id="@+id/more" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="加载下20条" /> <LinearLayout android:gravity="center" android:layout_gravity="center" android:orientation="horizontal" android:id="@+id/loading" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ProgressBar android:layout_gravity="center_vertical" android:id="@+id/footprogress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminateBehavior="repeat" style="?android:progressBarStyleSmallInverse" /> <TextView android:textColor="#ff000000" android:gravity="left|center" android:padding="3.0px" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加载中" /> </LinearLayout> </LinearLayout>
main_list.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:paddingBottom="4dip" android:paddingLeft="12dip" android:paddingRight="12dip" android:background="#FFFFFF" > <ImageView android:paddingTop="12dip" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/img" /> <TextView android:text="TextView01" android:layout_height="wrap_content" android:textSize="20dip" android:layout_width="fill_parent" android:id="@+id/listtitle" android:layout_toRightOf="@id/img" /> <TextView android:text="TextView02" android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/listtext" android:layout_toRightOf="@id/img" android:layout_below="@id/listtitle" /> </RelativeLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="false" android:footerDividersEnabled="false" android:scrollbars="vertical" /> </LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.anycall.testlist" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="4" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".TestListViewActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <!-- 允许应用打开网络套接口 --> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>