Android ListView异步加载数据库图片
2016-01-28 19:37
453 查看
需求:从数据库中得到图片的byte数据,编码成png图片,显示到ListView上
这里最大一个问题就是ListView滑动卡的问题,要解决卡,就需要用到异步加载数据库的图片;
原创博客,转载注明出处:http://blog.csdn.net/deng0zhaotai/article/details/50596332
程序第一次启动时会把assets中的数据库压缩文件复制到/data/data/packageName.../databases/目录下,这里使用的是网上找的一个工具类,详细代码可以在下面的链接下载,异步操作主要是在Adapter的getView()函数中处理,如果已经添加到缓存就直接取,否则会开启task去加载,下面看下ImageAdapter的详细代码,都有添加注释,应该不难理解
关键代码:
int inx = (int) image.getTag();
if (mIndex == inx) {
image.setImageBitmap(bitmap);
if (mListener != null) {
mListener.onLoadFinish(bitmap, mIndex);
}
}
本文可以学习到异步加载图片、防止item显示错位、图片缓存、解压压缩文件
代码下载链接:http://pan.baidu.com/s/1qXuwilu
这里最大一个问题就是ListView滑动卡的问题,要解决卡,就需要用到异步加载数据库的图片;
原创博客,转载注明出处:http://blog.csdn.net/deng0zhaotai/article/details/50596332
程序第一次启动时会把assets中的数据库压缩文件复制到/data/data/packageName.../databases/目录下,这里使用的是网上找的一个工具类,详细代码可以在下面的链接下载,异步操作主要是在Adapter的getView()函数中处理,如果已经添加到缓存就直接取,否则会开启task去加载,下面看下ImageAdapter的详细代码,都有添加注释,应该不难理解
package com.dzt.listviewshow; import java.util.List; import com.dzt.listviewshow.AsyncImageLoader.OnLoadFinishListener; import com.dzt.listviewshow.utils.LogUtils; import android.content.Context; import android.graphics.Bitmap; import android.support.v4.util.LruCache; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class ImageAdapter extends BaseAdapter { private Context context; private List<CarClass> carClass; private LayoutInflater mInflater; private LruCache<String, Bitmap> mMemoryCache; public ImageAdapter(Context context, List<CarClass> carClass) { this.context = context; this.carClass = carClass; mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // LruCache通过构造函数传入缓存值,以KB为单位。 int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 使用最大可用内存值的1/8作为缓存的大小。 int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { // 重写此方法来衡量每张图片的大小,默认返回图片数量。 return bitmap.getByteCount() / 1024; } }; } @Override public int getCount() { // TODO Auto-generated method stub return carClass.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return carClass.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub // 1获取item,再得到控件 // 2 获取数据 // 3绑定数据到item ViewHolder hodler = null; CarClass cc = carClass.get(position); if (convertView == null) { convertView = mInflater.inflate(R.layout.item, null); hodler = new ViewHolder(); hodler.tvView = (TextView) convertView.findViewById(R.id.tv_title); hodler.ivView = (ImageView) convertView.findViewById(R.id.iv_img); convertView.setTag(hodler); } else { hodler = (ViewHolder) convertView.getTag(); } hodler.ivView.setTag(cc.index); final Bitmap bitmap = getBitmapFromMemCache("" + cc.index); if (bitmap == null) { LogUtils.i("getView-----bitmap == null"); hodler.ivView.setImageResource(R.drawable.carback); // 异步的加载图片 (线程池 + Handler ) ---> AsyncTask asyncloadImage(hodler.ivView, cc); } else { LogUtils.i("getView-----bitmap != null"); hodler.ivView.setImageBitmap(bitmap); } hodler.tvView.setText("第 " + position + " 个 " + cc.carClass); return convertView; } private void asyncloadImage(ImageView iv_header, CarClass cc) { AsyncImageLoader task = new AsyncImageLoader(context, iv_header, cc.index, new LoadFinish()); task.execute(cc.bitmap); } class ViewHolder { ImageView ivView; TextView tvView; } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); } class LoadFinish implements OnLoadFinishListener { @Override public void onLoadFinish(Bitmap bitmap, int index) { // TODO Auto-generated method stub LogUtils.i("onLoadFinish-----index = " + index); addBitmapToMemoryCache(String.valueOf(index), bitmap); } } }为了防止滑动过快时错位显示,需要在getview函数为ImageView加上hodler.ivView.setTag(cc.index);,在异步加载时根据Tag是否显示
package com.dzt.listviewshow; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.widget.ImageView; public class AsyncImageLoader extends AsyncTask<byte[], Void, Bitmap> { private Context mContext; private ImageView image; private int mIndex; private OnLoadFinishListener mListener; /** * 构造方法,需要把ImageView控件和LruCache 对象传进来 * * @param image * 加载图片到此 {@code}TextView * @param lruCache * 缓存图片的对象 */ public AsyncImageLoader(Context context, ImageView image, int index, OnLoadFinishListener listener) { mContext = context; this.image = image; mIndex = index; mListener = listener; } @Override protected Bitmap doInBackground(byte[]... params) { // TODO Auto-generated method stub return getBitmap(params[0]); } @Override protected void onPostExecute(Bitmap bitmap) { int inx = (int) image.getTag(); if (mIndex == inx) { image.setImageBitmap(bitmap); if (mListener != null) { mListener.onLoadFinish(bitmap, mIndex); } } } // 解析图片 private Bitmap getBitmap(byte[] icon) { return BitmapFactory.decodeByteArray(icon, 0, icon.length); } interface OnLoadFinishListener { public void onLoadFinish(Bitmap bitmap, int index); } }
关键代码:
int inx = (int) image.getTag();
if (mIndex == inx) {
image.setImageBitmap(bitmap);
if (mListener != null) {
mListener.onLoadFinish(bitmap, mIndex);
}
}
本文可以学习到异步加载图片、防止item显示错位、图片缓存、解压压缩文件
代码下载链接:http://pan.baidu.com/s/1qXuwilu
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件