您的位置:首页 > 移动开发 > Android开发

Android ListView异步加载图片错位解决方案一 使用findViewWithTag

2016-07-15 14:09 585 查看
* 解决listView 加载图片错位解决方案一 使用findViewWithTag *

使用findViewWithTag必须要有ListView的实例,在Adapter中怎样才能获取到ListView的实例呢?,getView()方法中传入的第三个参数其实就是ListView的实例 我们定义一个全局变量mListView ,然后在getView()方法中判断它是否为空, 如果为空就把parent这个参数赋值给它。

,,另外一个操作就是在getView()方法中我们调用了ImageView的setTag()方法,并把当前位置图片的URL地址作为参数传了进去,这个是为后续的findViewWithTag()方法做准备.

最后,我们修改了BitmapWorkerTask的构造函数,这里不再通过构造函数把ImageView的实例传进去了,而是在onPostExecute()方法当中通过ListView的findVIewWithTag()方法来去获取ImageView控件的实例。获取到控件实例后判断下是否为空,如果不为空就让图片显示到控件上。

显示图片的 Adapter

package com.gaoo.listviewtest;

/**
* 1.设置布局文件主界面 listview 和新建一个 item 布局
* 2.新建ImageAdapter做为ListView的适配器
*
* 解决listView 加载图片错位
* 解决方案一  使用findViewWithTag
*/
public class ImageAdapter extends ArrayAdapter<String> {
private ListView mListView; //定义一个全局变量 listview
/**
* 图片缓存技术的核心类 ,用于缓存所有下载的图片,在程序内存达到设定值时,会将最少最近使用的图片移除掉.
*/
private LruCache<String, BitmapDrawable> mMemoryCache;

public ImageAdapter(Context context, int resource, String[] objects) {
super(context, resource, objects);
//获取应用程序的最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
//大小为当前程序运行时内存的1/8
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, BitmapDrawable>(cacheSize) {
@Override
protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount();
}
};
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 第1.解决方案一  使用findViewWithTag
if (mListView == null) {
mListView = (ListView) parent;
}
String url = getItem(position); //根据当前的位置获取到图片的URL地址

View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.item_image, null);
} else {
view = convertView;
}
ImageView imageView = (ImageView) view.findViewById(R.id.image);

//第2.解决方案一  使用findViewWithTag
imageView.setImageResource(R.drawable.empty_photo);
imageView.setTag(url);

//先从缓存中获取
BitmapDrawable drawable = getBitmapFromMemoryCache(url);
if (drawable != null) {
imageView.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 url LruCache的键,传入图片的URL地址。
* @return
*/
public BitmapDrawable getBitmapFromMemoryCache(String url) {
return mMemoryCache.get(url);
}
/**
* 异步下载图片的任务。
*/
private class BitmapWorkerTask extends AsyncTask<String, Void, BitmapDrawable> {
private ImageView mImageView;
private String mImageUrl;
//        public BitmapWorkerTask(ImageView imageView) {
//            this.mImageView = imageView;
//        }
@Override
protected BitmapDrawable doInBackground(String... params) {
mImageUrl = params[0];
Log.d("BitmapWorkerTask-------", "从网络上获取");
//在后台 开始下载图片
Bitmap bitmap = downloadBitmap(mImageUrl);
BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), bitmap);
addBitmapToMemoryCache(mImageUrl, drawable);
return drawable;
}
@Override
protected void onPostExecute(BitmapDrawable drawable) {
//第3.解决方案一  使用findViewWithTag
ImageView imageView = (ImageView) mListView.findViewWithTag(mImageUrl);
if (imageView != null && drawable != null) {
imageView.setImageDrawable(drawable);
}
//            if (mImageView != null && drawable != null) {
//                mImageView.setImageDrawable(drawable);
//            }
}
/**
* 建立网络请求,并获取 bitmap 对象
*
* @param imageUrl 图片的URL地址
* @return
*/
private Bitmap downloadBitmap(String imageUrl) {
Bitmap bitmap = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(imageUrl);
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setConnectTimeout(20 * 1000);
urlConnection.setReadTimeout(10 * 1000);
InputStream is = urlConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}

return bitmap;
}
}
}


主界面

/**
* Android ListView异步加载图片乱序问题,原因分析及解决方案
* 原文地址 : http://blog.csdn.net/guolin_blog/article/details/45586553 ImageId 图片资源可以在 原文地址 中 查找
*/
public class MainActivity extends AppCompatActivity {
ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);

//        //方法3 解决方案一 使用findViewWithTag
ImageAdapter adapter = new ImageAdapter(this,0, ImageId.imageUrl);
listView.setAdapter(adapter);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息