前言
项目需要大规模的从后端下载图片在app上显示。前期使用了Google推荐的BitmapFun,而没有考虑使用第三方的库,实际使用过程中,发现需要大段的修改源码,成本极高。最近使用Universal Image Loader的第三方开源库,实际效果比较理想。
使用
转载一篇出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303)
主要的配置和基本的实现在本文中都有提及。
坑
实际使用的时候还是遇到的很多坑。这里总结一下。
问题1:
刷新闪屏的问题
.showImageOnLoading(R.drawable.empty_photo) // resource or drawable在Loader Image Options 如果配置了该项,那么加载图片资源时,都会先加载该图,然后才会加载资源图。这样就会造成如下拉刷新闪屏的情况。
如何处理呢。
下面是建议的解决方法:
对于ListView,GridView,RecyclerView等,需要编写自己的ViewHolder,将资源的URI绑定到Image的Tag上。
下次刷新时,判断记录的Tag与URI是否一致,如果一致就不重新加载。
if (!music.albumArtUrl.equals(holder.ivPoster.getTag())) { holder.ivPoster.setTag(music.albumArtUrl); imageFetcher.displayImage(music.albumArtUrl, holder.ivPoster, ImageLoaderOption.getOption()); }
问题2:
ListView和GridView提供了setOnScrollListener(new PauseOnScrollListener(mImageFetcher, true, true))的方法滑动时,可以禁止加载图片。对于RecyclerView没有此方法,这里没有其他方法,只能自己写一个禁止刷新的类。代码如下即可解决。public class NewPauseOnScrollListener extends RecyclerView.OnScrollListener { private ImageLoader imageLoader; private final boolean pauseOnScroll; private final boolean pauseOnSettling; private final RecyclerView.OnScrollListener externalListener; public NewPauseOnScrollListener(ImageLoader imageLoader, boolean pauseOnScroll, boolean pauseOnSettling) { this(imageLoader, pauseOnScroll, pauseOnSettling, null); } public NewPauseOnScrollListener(ImageLoader imageLoader, boolean pauseOnScroll, boolean pauseOnSettling, RecyclerView.OnScrollListener customListener) { this.imageLoader = imageLoader; this.pauseOnScroll = pauseOnScroll; this.pauseOnSettling = pauseOnSettling; externalListener = customListener; } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { Log.e("Recycle Scroll","state:"+newState); switch (newState) { case RecyclerView.SCROLL_STATE_IDLE: imageLoader.resume(); break; case RecyclerView.SCROLL_STATE_DRAGGING: if (pauseOnScroll) { imageLoader.pause(); } break; case RecyclerView.SCROLL_STATE_SETTLING: if (pauseOnSettling) { Log.e("Recycle Scroll","Pause"); imageLoader.pause(); } break; } if (externalListener != null) { externalListener.onScrollStateChanged(recyclerView, newState); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (externalListener != null) { externalListener.onScrolled(recyclerView, dx, dy); } }
问题3:
按照上面的两个方法编写后,发现快速下滑的时候出现图片位置不对的情况。
本来应该是空图的情况下显示的图为其他图标。
在快速滑动的时候,实际发现TAG的标签绑定对应的POSITION,可能会错位。
从代码角度看,就算是错位,刷新的图片也应该会重新加载空图。
这里看一下错误的源码:
if (music.albumArtUrl==null) { holder.ivPoster.setImageResource(R.drawable.ic_broken_image); } else { if (!music.albumArtUrl.equals(holder.ivPoster.getTag())) { holder.ivPoster.setTag(music.albumArtUrl); imageFetcher.displayImage(music.albumArtUrl, holder.ivPoster, ImageLoaderOption.getOption());
} 错误就在红色标注的这行。
Universal Image Loader是一个单实例多Task加载的插件。在Image Pause的时候,还是会有队列加入到图片加载队列中,等待刷新完成后才会加载。
而setImageResource是立即执行的,这就造成时序上的错位。空图先加载,错位的非空图后加载。
解决的办法是空图也使用ImageLoader的方法进行加载。这样时序就不会错乱了。
本文介绍了在使用 UniversalImageLoader 过程中遇到的几个常见问题及其解决方案,包括刷新时的闪屏问题、RecyclerView 图片加载控制及快速下滑时图片错位的问题。
308

被折叠的 条评论
为什么被折叠?



