今天,简单讲讲android里再listview调用notifyDataSetChanged刷新界面时,Imageloader加载图片会闪烁的问题。

最近,发现app里的listview图片会出现闪烁的情况。我发现是由于调用notifyDataSetChanged这个方法时候,图片全部闪烁一下,原因是图片全部重新加载了一次,导致闪烁。后来修改为局部刷新,但是还是还是存在是不是闪烁的情况,于是在网上查找资料,最终解决了问题。这里记录一下。


一.网上无用的解决代码

网上关于图片闪烁的解决代码很多,但是大多不是我想要的。比如有人说:

    真正的闪烁原因不是display和imageload方法的缘故,而是在设置option时,设置了.displayer(new FadeInBitmapDisplayer(200))的缘故,直接设置为.displayer(new SimpleBitmapDisplayer()),然后再getview方法中调用display方法,就不会闪烁了.这个我试过了,没有一点效果。

还有人说:

在一个频繁刷新的ListView中使用ImageLoader后,在某些手机上会发现图片闪动。经过分析,原来是DisplayImageOptions的问题。

之前的DisplayImageOptions是这样写的:

imageOptions = new DisplayImageOptions.Builder().bitmapConfig(Bitmap.Config.RGB_565).showStubImage(R.drawable.icon_default)                       .showImageForEmptyUri(R.drawable.icon_default).showImageOnFail(R.drawable.icon_default).cacheInMemory(true)                       .cacheOnDisc(true).build();  

其中的showStubImage()造成了加载前先显示默认图片的问题,造成了闪动。修改为以下代码后就正常了:

imageOptions = new DisplayImageOptions.Builder().bitmapConfig(Bitmap.Config.RGB_565)                       .showImageForEmptyUri(R.drawable.icon_default).showImageOnFail(R.drawable.icon_default).cacheInMemory(true)                       .cacheOnDisc(true).build();  
这个只是解决加载图片前显示默认加载图片的问题,和我的因为频繁刷新导致的问题不一样。

二.解决问题的代码

下面是我之前的getView方法中。下面的ImageLoader直接调用,造成每次notifyDataSetChanged,重新调用了ImageLoader方法。

 @Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = LayoutInflater.from(context).inflate(R.layout.item_app_wall2, parent, false);holder = new ViewHolder();holder.icon = (ImageView) convertView.findViewById(R.id.app_icon);holder.name = (MarqueeText) convertView.findViewById(R.id.app_name);// holder.grade = (ImageView)// convertView.findViewById(R.id.grade);holder.size = (TextView) convertView.findViewById(R.id.app_size);holder.count = (TextView) convertView.findViewById(R.id.app_count);holder.ratingBar = (RatingBar) convertView.findViewById(R.id.grade);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ImageLoader.getInstance().displayImage(searchAppList.get(position).getHttpIco(), holder.icon,DisplayImageOptionUtil.getInstance().getOptions());holder.name.setText(searchAppList.get(position).getName().trim());holder.size.setText(CommonUtil.format(searchAppList.get(position).getApkSize() / (float) 1024) + "M");AppStatistics statistics = searchAppList.get(position).getAppStatistics();if (statistics != null) {holder.count.setText(statistics.getDownloadCount() + "次");}holder.ratingBar.setRating(searchAppList.get(position).getAveccore() / 2f);return convertView;}

下面我做出了修改,如果当前图片是之前的图片,则不会调用ImageLoader,否则调用ImageLoader。

public View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = LayoutInflater.from(context).inflate(R.layout.item_app_wall2, parent, false);holder = new ViewHolder();holder.icon = (ImageView) convertView.findViewById(R.id.app_icon);holder.name = (MarqueeText) convertView.findViewById(R.id.app_name);// holder.grade = (ImageView)// convertView.findViewById(R.id.grade);holder.size = (TextView) convertView.findViewById(R.id.app_size);holder.count = (TextView) convertView.findViewById(R.id.app_count);holder.ratingBar = (RatingBar) convertView.findViewById(R.id.grade);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}if (searchAppList.get(position).getHttpIco().equals(holder.icon.getTag())) {} else {// 如果不相同,就加载。现在在这里来改变闪烁的情况ImageLoader.getInstance().displayImage(searchAppList.get(position).getHttpIco(), holder.icon,DisplayImageOptionUtil.getInstance().getOptions());holder.icon.setTag(searchAppList.get(position).getHttpIco());}holder.name.setText(searchAppList.get(position).getName().trim());holder.size.setText(CommonUtil.format(searchAppList.get(position).getApkSize() / (float)1024) + "M");AppStatistics statistics = searchAppList.get(position).getAppStatistics();if (statistics != null){holder.count.setText(statistics.getDownloadCount() + "次");}holder.ratingBar.setRating(searchAppList.get(position).getAveccore() / 2f);return convertView;}

通过ImageView.getTag和setTag方法来,判定当前图片是否是之前的,如果是之前,则不会刷新图片,如果不是,再刷新。

简单讲讲,其实就是在每次getView时,ImageView通过setTag将家中图片的路径保存起来,当调用notifyDataSetChanged时,需要刷新界面,首先判断需要重新加载的图片路径和ImageView.getTag是否相同,如果相同,就不需要重新加载,这样避免了无用的重复加载相同图片。


android 解决listview.notifyDataSetChanged刷新时Imageloader加载图片闪烁问题就讲完了。


就这么简单。

更多相关文章

  1. 【Android】PopupWindow中使用listview,listview的点击事件响应很
  2. 【Android】Handler的应用(一):从服务器端加载JSON数据
  3. Android的schedule、AlarmService、Timer定时器机制
  4. android TextView 加载html 显示图片并且添加img标签点击事件工
  5. android开发-NDK-JNI入门教程
  6. android webview加载不出ajax的问题
  7. Android(安卓)View 绘制刷新流程分析
  8. Android(安卓)使用Scroller实现绚丽的ListView左右滑动删除Item
  9. Android学习中遇到的优秀文章的总结(持续更新)

随机推荐

  1. Android(安卓)Timer 更好方法
  2. Android(安卓)listView
  3. android模拟器上网
  4. Android(安卓)下压缩图片—微弱失真
  5. CreateProcess error = 2,系统找不到指定
  6. android程序排序算法实现
  7. Android(安卓)IMF学习笔记二
  8. android framework java层服务 分析
  9. Android(安卓)Activity生命周期
  10. 移动端判断是android手机还是ios手机