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控件的实例。获取到控件实例后判断下是否为空,如果不为空就让图片显示到控件上。
使用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); } }
相关文章推荐
- 使用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的关闭事件
- SourceProvider.getJniDirectories