ListView图片优化(一)---findViewWithTag
来源:互联网 发布:windows防火墙打不开 编辑:程序博客网 时间:2024/06/09 22:24
转自 郭霖
由于使用findViewWithTag必须要有ListView的实例才行,那么我们在Adapter中怎样才能拿到ListView的实例呢?getView()方法中传入的第三个参数其实就是ListView的实例,那么这里我们定义一个全局变量mListView,然后在getView()方法中判断它是否为空,如果为空就把parent这个参数赋值给它。
另外在getView()方法中我们还做了一个操作,就是调用了ImageView的setTag()方法,并把当前位置图片的URL地址作为参数传了进去,这个是为后续的findViewWithTag()方法做准备。
这里我们可以尝试分析一下findViewWithTag的工作原理,其实顾名思义,这个方法就是通过Tag的名字来获取具备该Tag名的控件,我们先要调用控件的setTag()方法来给控件设置一个Tag,然后再调用ListView的findViewWithTag()方法使用相同的Tag名来找回控件。
那么为什么用了findViewWithTag()方法之后,图片就不会再出现乱序情况了呢?其实原因很简单,由于ListView中的ImageView控件都是重用的,移出屏幕的控件很快会被进入屏幕的图片重新利用起来,那么getView()方法就会再次得到执行,而在getView()方法中会为这个ImageView控件设置新的Tag,这样老的Tag就会被覆盖掉,于是这时再调用findVIewWithTag()方法并传入老的Tag,就只能得到null了,而我们判断只有ImageView不等于null的时候才会设置图片,这样图片乱序的问题也就不存在了。
ImageAdapter
package com.example.listviewyouhua;import java.net.HttpURLConnection;import java.net.URL;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.BitmapDrawable;import android.os.AsyncTask;import android.support.v4.util.LruCache;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.ListView;public class ImageAdapter extends ArrayAdapter<String> {/** * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。 */private LruCache<String, BitmapDrawable> mMemoryCache;private ListView mListView;/** * 构造方法:获取图片缓存的大小内存 * * @param context * @param resource * @param objects */public ImageAdapter(Context context, int resource, String[] objects) {super(context, resource, objects);// 获取应用程序最大可用内存int maxMemory = (int) Runtime.getRuntime().maxMemory();int cacheSize = maxMemory / 8;mMemoryCache = new LruCache<String, BitmapDrawable>(cacheSize) {@Overrideprotected int sizeOf(String key, BitmapDrawable drawable) {return drawable.getBitmap().getByteCount();}};}@Override public View getView(int position, View convertView, ViewGroup parent) { if (mListView == null) { mListView = (ListView) parent; } String url = getItem(position); View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.image_item, null); } else { view = convertView; } ImageView image = (ImageView) view.findViewById(R.id.image); image.setImageResource(R.drawable.ic_launcher); ///////////////关键代码/////////////// image.setTag(url); BitmapDrawable drawable = getBitmapFromMemoryCache(url); if (drawable != null) { image.setImageDrawable(drawable); } else { BitmapWorkerTask task = new BitmapWorkerTask(); task.execute(url); } return view; } /** * 将一张图片存储到LruCache中。 * * @param key * LruCache的键,这里传入图片的URL地址。 * @param drawable * LruCache的值,这里传入从网络上下载的BitmapDrawable对象。 */public void addBitmapToMemoryCache(String key, BitmapDrawable drawable) {if (getBitmapFromMemoryCache(key) == null) {mMemoryCache.put(key, drawable);}}/** * 从LruCache中获取一张图片,如果不存在就返回null。 * * @param key * LruCache的键,这里传入图片的URL地址。 * @return 对应传入键的BitmapDrawable对象,或者null。 */public BitmapDrawable getBitmapFromMemoryCache(String key) {return mMemoryCache.get(key);}/** * 异步下载图片的任务。 * * @author guolin */class BitmapWorkerTask extends AsyncTask<String, Void, BitmapDrawable> { String imageUrl; public BitmapWorkerTask() {}@Override protected BitmapDrawable doInBackground(String... params) { imageUrl = params[0]; // 在后台开始下载图片 Bitmap bitmap = downloadBitmap(imageUrl); BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), bitmap); addBitmapToMemoryCache(imageUrl, drawable); return drawable; } @Override protected void onPostExecute(BitmapDrawable drawable) { ImageView imageView = (ImageView) mListView.findViewWithTag(imageUrl); if (imageView != null && drawable != null) { imageView.setImageDrawable(drawable); } } /** * 建立HTTP请求,并获取Bitmap对象。 * * @param imageUrl * 图片的URL地址 * @return 解析后的Bitmap对象 */private Bitmap downloadBitmap(String imageUrl) {Bitmap bitmap = null;HttpURLConnection con = null;try {URL url = new URL(imageUrl);con = (HttpURLConnection) url.openConnection();con.setConnectTimeout(5 * 1000);con.setReadTimeout(10 * 1000);bitmap = BitmapFactory.decodeStream(con.getInputStream());} catch (Exception e) {e.printStackTrace();} finally {if (con != null) {con.disconnect();}}return bitmap;}}}
- ListView图片优化(一)---findViewWithTag
- Android ListView异步加载图片错位解决方案一 使用findViewWithTag
- 在优化listview,滑动停止时异步加载图片,absListView.findViewWithTag(i)返回值为null的原因分析
- ListView解决图片错乱为什弱引用相关比findViewWithTag效率要高?
- android ListView 异步下载图片 优化一
- listview和gridView中findViewWithTag的使用
- ListView的优化(一)
- ListView的优化(一)
- ListView图片优化(三)---练习
- listview和gridView中findViewWithTag和setTag使用
- Android性能优化 (一)- ListView
- ListView优化总结(一)--Android
- ListView的优化总结(一)
- ListView优化(一) 总结
- Android listview 优化 一
- listview异步图片加载优化
- ListView 优化 图片三级缓存
- ListView 原理 图片缓存 优化
- CryptoAPI例子-最全1
- 安装成功的nginx如何添加未编译安装模块
- 工作环境搭建(8) - CentOS7命令行安装Android SDK
- 向前奔跑中、、、
- 广点通sdk接入 _应用墙广告
- ListView图片优化(一)---findViewWithTag
- SMS服务API设计
- View hierarchy-视图层次
- 学习CRYPTO第二天
- 03、3分钟教你搞定这该死的Delegate!代理与协议委托的深度理解
- JavaScript 文章备注
- 直接修改别人jar包里面的class文件 工具:jclasslib
- java synchronized
- 威佐夫博奕