【问题标题】:getView is called several times for the first position in GridViewGridView 中第一个位置多次调用 getView
【发布时间】:2012-10-10 16:46:12
【问题描述】:

我有一个带有这个 getView 的适配器:

public View getView(int position, View convertView, ViewGroup parent) {
    Log.d("getView gv", position+"");

    NewsLine holder = null;

    if (convertView == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        convertView = inflater.inflate(R.layout.grid_entry, parent, false);
        holder = new NewsLine();

        holder.iv= (ImageView) convertView.findViewById(R.id.photo);

        convertView.setTag(holder);
    } else {
        holder = (NewsLine) convertView.getTag();
    }

    NewsItem item=news.ITEMS.get(position);
    //---------

    if(item.imgurl!=null && item.imgurl.compareToIgnoreCase("null")!=0) 
    {
        holder.iv.setVisibility(View.VISIBLE);     
        mMemoryCache.loadBitmap(item.imgurl, holder.iv,position);
    }
    else
        holder.iv.setVisibility(View.INVISIBLE);
    //-------------




    return convertView;
}

我有两个问题:

  1. 对于位置 0,多次调用 getView(如果在 LruCache 中丢失位图,则使用 AsyncTask 下载位图)。我有一个动画(从 0 到 1 的 alpha),该位置会重新启动几次。

  2. 因为我正在回收视图,所以有时您可以在几分之一秒内看到旧的 imageView 内容。

//----

这里是缓存类(只有堆):

public class SetImgAT extends LruCache<String, Bitmap> {
private static SetImgAT instance;   
private Animation FadeInAnimation;

private SetImgAT(int size, Context context) {
    super(size);
    FadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fadein);
}

public static synchronized SetImgAT getInstance(int size, Context context) {
    if (instance == null) {
        instance = new SetImgAT(size, context);
    }
    return instance;
}

@Override
protected int sizeOf(String key, Bitmap value) {
    return (value.getRowBytes() * value.getHeight());
}

public void loadBitmap(String url, ImageView imageView,int pos) {
    Bitmap bitmap = instance.get(url.hashCode() + "");
    if (bitmap != null) {
        Log.d("ImageCache", "hit - "+url.hashCode()+"pos:"+pos);
        imageView.setImageBitmap(bitmap);

        imageView.invalidate();
    } else {
        Log.d("ImageCache", "miss");
        BitmapWorkerTask task = new BitmapWorkerTask(imageView);
        task.execute(url);
    }
}

class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    ImageView mImageView;

    public BitmapWorkerTask(ImageView imageView) {
        mImageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(String... url) {
        Bitmap Picture = null;


        if (url[0] != null && url[0].compareToIgnoreCase("null") != 0) {
            Log.d("GetBMP from", url[0]);

            URL img_value = null;
            try {
                img_value = new URL(url[0]);
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                Picture = BitmapFactory.decodeStream(img_value
                        .openConnection().getInputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (Picture == null) {
                Log.d("deb", "no bitmap");
            } else {
                Log.d("got deb", "got bitmap to "+url[0].hashCode());                   
                instance.put(url[0].hashCode()+"", Picture);
            }

        }
        return Picture;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        // super.onPostExecute(result);
        if (result != null) {
            Log.d("deb", "set bitmap");
            mImageView.setImageBitmap(result);
            //mImageView.startAnimation(FadeInAnimation);
        }

    }
}

//----------------

}

谢谢! :)

【问题讨论】:

  • 对于问题 #2,尝试在setVisibility() 之前调用mMemoryCache.loadBitmap() 以防止出现旧图像。
  • "getView 多次调用位置 0" -- 这是完全正常的行为。对于某个职位将调用多少次getView() 没有规定。总的来说,StackOverflow 是针对编程问题的,而你没有问过问题。
  • Sam,它没用,似乎还有很多事情需要处理,我将通过 developer.android.com/training/displaying-bitmaps/… 缓存位图的示例。在 CommonsWare 谢谢你,我认为我不需要重新表述这个问题,也许你可以试试。
  • 我也遇到了这个问题。每次在我的网格视图中出现新行时,似乎位置 0 被调用 2 次。很奇怪
  • @CommonsWare 这是否被认为是“正常的”,因为它会触发多次?

标签: android


【解决方案1】:

我在来回滚动或随意调用 notifyDataSetChanged() 时看到了类似的行为。

作为对您现在所做工作的增强,我建议您改用 Picasso,因为它可以很好地处理这种情况,除了动画的淡入淡出。

你的 getView() 中的一个衬里:

Picasso.with(context).load(urlToLoad).into(imageView);

见: http://square.github.io/picasso/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 2014-11-04
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多