1.ListView 的item 图片错乱问题
前面一篇整理了解析Json数据后显示到listview上,关于图片加载没有多做解释,在运行的过程中出现了item 图像错乱的问题,后来查了资料才知道,因为listview的缓存机制,正确的item 没有对应正确的图片URL,所以更新UI 时出现了错乱,解决方法也分简单:就是给imgeview 加个tag,然后需要更新UI时先判断tag是否正确(我是将URL作为图片的tag),正确才可以更新UI。
imageview.setTag(XXXX);
imageview.getTag(XXXX);
2.将加载过的图片放在缓存中,这样加载过的图片就不需要再去加载,节省流量。Android提供了一个不错的类LruCache类,我整理了一下使用注意点:(重要的部分还要重点学习)
创建LruCache mCache ——>初始化LruCache:
mCache=new LruCache<String,Bitmap>(cachesize){
@Override
protected int sizeOf(String key, Bitmap value) {
//在每次存入缓存时调用
return value.getByteCount();
}
};
LruCache(K,V)中,K:需要保存的名字;V:需要保存的对象;
cachesize 一般是可用内存(
MaxMemory= (int) Runtime.getRuntime().maxMemory())的1/4.
sizeOf()返回的是存储图片需要的内存。
3.添加两个方法:
public void addBitmapToCache(String Url,Bitmap bitmap){
if(getBitmapFromCache(Url)==null){
mCache.put(Url,bitmap);
}
}
public Bitmap getBitmapFromCache(String Url){
return mCache.get(Url);
}
这样在主程序中就可以判断,如果缓冲中已经有了该图片,就不加载,直接从缓冲中取得,如果没有的话,就启动线程加载,并同时把返回的图片存储在cache 中。
3.控制ListView滑动时不加载:
适配器实现OnScrollListenner接口,重写两个主要的方法:
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==SCROLL_STATE_IDLE){
//没有滚动项,开始加载
imageLoader.LoadImages(mStart,mEnd);//没有进行预加载
}else{
//停止加载
imageLoader.CancelAllTask();
}
}
/**
*
* @param view 可见视图
* @param firstVisibleItem 第一个可见元素
* @param visibleItemCount 可见元素数目
* @param totalItemCount list 中的总数
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
mStart=firstVisibleItem;
mEnd=firstVisibleItem+visibleItemCount;
if(mFirst&&visibleItemCount>0){//当前列表第一次启动而且item已经绘出
imageLoader.LoadImages(mStart,mEnd);
mFirst=false;
}
}
然后记得要注册监听器。
接着加载指定区间的图片:
public void LoadImages(int start,int end){
for (int i = start; i <end; i++) {
String Url=NewsAdapter.Urls[i];//获得Url
Bitmap bitmap=getBitmapFromCache(Url);
if(bitmap==null){
MyAsyncTask task=new MyAsyncTask(Url);//因为现在是通过tag找到imageview,所以直接通过imageview设置就不合理
mtask.add(task);
}else{
ImageView imagview= (ImageView) mlistview.findViewWithTag(Url);//通过URL获得imageview
imagview.setImageBitmap(bitmap);
}
}