Android的BaseAdapter随着LruCache一些UI问题 [英] Android BaseAdapter With LruCache Some ui problems

查看:290
本文介绍了Android的BaseAdapter随着LruCache一些UI问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现到与底座适配器和LruCache的帮助下接触的所有图像的列表视图。但在屏幕上所有的图像(对应于视图)一幅长长的画卷正在设置实际的图像之前显示。

I am trying to implement to a list view with all contact images with the help of base adapter and LruCache. But on a long scroll on screen all the images(corresponding to that view) are displayed before setting actual image.

例如:每页5个项目,如果我们从第一次接触到第60位,上1,6,11,16,21..51列表视图图像的第一个视图滚动列表视图中显示前几毫秒55图像显示

eg: list view with 5 items per page, if we scrolled from first contact to 60th, on first view of list view images of 1,6,11,16,21..51 are displayed for a few milli seconds before the 55th images is shown

主要codeS是

//Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = (ImageView) convertView;
if(imageView == null){
 imageView = new ImageView(getActivity());
}    
int id =  contactId[position];
final String imageKey = String.valueOf(contactId);
final Bitmap bitmap = cache.get(imageKey);
if (bitmap != null) {
  imageView.setImageBitmap(bitmap);
} else {    
  Resources res = context.getResources();
  BitmapManager bm = new BitmapManager(imageView, res, cache);
  bm.setContext(getActivity());
  bm.execute(id);
}
return imageView;
}

BitmapManager后执行code

BitmapManager Post Execute Code

@Override
protected void onPostExecute(Bitmap bitmap) {
    // TODO Auto-generated method stub
    try{
        if(isCancelled()){
            bitmap = null;
        }
        if(imageViewReference != null && bitmap != null){
            ImageView imageView = imageViewReference.get();
            imageView.setImageBitmap(bitmap);
            cache.put(String.valueOf(res), bitmap);
            if(imageView != null){
                imageView.setImageBitmap(bitmap);
            }

        }
    }catch(Exception e){

    }
    super.onPostExecute(bitmap);
}

如何解决这个问题。
谢谢

How to solve this problem. Thanks

推荐答案

当你向下滚动,你的观点得到重用对于映入眼帘的新的列表中的位置。既然你每个getView被调用时开始一个新的BitmapManager的任务,这些任务获得一字排开,等待更新图像。当他们完成各自的装载位图,他们把它变成为了在ImageView的,这是你所看到的。

As you scroll down, your views get reused for new list positions that come into view. Since you start a new BitmapManager task each time getView is called, the tasks get lined up, waiting to update the image. As they each finish loading their bitmap, they put it into the ImageView in order, which is what you are seeing.

看起来你试图使用到的ImageView的引用避免使用位图它滚出视后,却没有工作的原因是该适配器回收利用ImageViews,所以参考保持有效,即使在现实中正在使用的ImageView的一个不同的列表项现在

It looks like you were trying to use a reference to the ImageView to avoid using the bitmap after it was scrolled out of view, but the reason that didn't work is that the adapter is recycling your ImageViews, and so the reference stays valid, even though in reality the ImageView is being used for a different list item now.

有不同的方法来解决这个问题,但我想到的最简单的就是用一个列表索引,而不是本身的ImageView来构建你的BitmapManager。然后在getView你可以保持地图上的什么位置什么正在使用的意见。当BitmapManager完成后,检查是否有针对你刚刚加载到缓存位置上的电流ImageView的。如果没有,那么什么也不做。

There are different ways to solve this, but the simplest that comes to mind is to construct your BitmapManager with a list index, rather than the ImageView itself. Then in getView you can keep a map of what views are being used on what positions. When BitmapManager finishes, check if there is a current ImageView for the position that you've just loaded into the cache. If not, then do nothing.

下面是一些code,显示我在说什么。我没有尝试,所以道歉,如果有错误。

Here is some code that shows what I'm talking about. I didn't try it, so apologies if there are errors.

//Adapter
private SparseArray<ImageView> ivMap = new SparseArray<ImageView>();
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView = (ImageView) convertView;
    if(imageView == null){
      imageView = new ImageView(getActivity());
    } else {
      // If recycled, remove the ImageView's previous position from map
      int oldPosition = ivMap.indexOfValue(imageView);
      if (oldPosition >= 0) {
        ivMap.remove(oldPosition);
      }
    }
    // Keep track of which view is representing this position
    ivMap.put(position, imageView);

    int id =  contactId[position];
    final String imageKey = String.valueOf(contactId);
    final Bitmap bitmap = cache.get(imageKey);
    if (bitmap != null) {
      imageView.setImageBitmap(bitmap);
    } else {    
      Resources res = context.getResources();
      BitmapManager bm = new BitmapManager(ivMap, position, res, cache);
      bm.setContext(getActivity());
      bm.execute(id);
    }
    return imageView;
}

//BitmapManager
@Override
protected void onPostExecute(Bitmap bitmap) {
    // TODO Auto-generated method stub
    try{
        if(isCancelled()){
            bitmap = null;
        }
        if(bitmap != null){
            cache.put(String.valueOf(res), bitmap);
            ImageView imageView = ivMap.get(position);
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }catch(Exception e){

    }
    super.onPostExecute(bitmap);
}

这篇关于Android的BaseAdapter随着LruCache一些UI问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆