android listview分页异步加载图片及图片缓存

来源:互联网 发布:cnzz 阿里云备案 编辑:程序博客网 时间:2024/04/26 19:14

引用
我是开发android的新手,参考了很多大牛的资料,才完成这个demo的,分享出来和大家一同学习

AsyncImageLoader.java

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.java 

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.java 

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;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);myHandler = new MyHandler();ListView listView = getListView();// 得到ListViewLinearLayout listFooter = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.main_foot, null);listView.addFooterView(listFooter);// 添加FooterViewbutton = (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) {asyncImageLoader = new AsyncImageLoader();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://www.1860.cn/tuangou/groupon/img/logo_v4.png",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发送消息,更新UItry {Thread.sleep(5000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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);}// 子类必须重写此方法,接受数据@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);// 此处可以更新UIBundle b = msg.getData();String rmsg = b.getString("rmsg");if ("1".equals(rmsg)) {// do nothingbutton.setVisibility(View.GONE);layloading.setVisibility(View.VISIBLE);}else if ("2".equals(rmsg)) { try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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.xml 

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>  
main_list.xml 
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_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>


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>


转载自:http://yafei.iteye.com/blog/1160207