ArrayAdapter的getView与图像下载不一致

我有GridView,其中图像正在从服务器下载,我已经使用延迟加载方法将图像异步添加到网格。

我可以看到getView方法被多次调用,并且不一致地用于网格视图的位置,直到图像被下载用于位置。

现在,当我滚动gridview时,已经下载了位置的图像现在正在被其他图像取代。

但是,在所有图像下载完毕后,它都可以正常工作。

我知道并已阅读以前的帖子,因为getView调用不一致,但仍无法解决问题。

`@Override public View getView(final int position,View convertView,final ViewGroup viewGroup){ViewHolder viewHolder;

    if (convertView == null) {
        convertView = layoutInflater.inflate(R.layout.ondemand_grid_item,
                null);

        viewHolder = new ViewHolder();
        viewHolder.title = ((TextView) convertView
                .findViewById(R.id.ondemand_grid_item_title));
        viewHolder.image = ((ImageView) convertView
                .findViewById(R.id.ondemand_grid_item_image));
        viewHolder.iconImage = ((ImageView) convertView
                .findViewById(R.id.on_demand_trailer_icon));
        viewHolder.showSelectedImage = (ImageView) convertView.findViewById(R.id.ondemand_grid_item_img);
        viewHolder.showSelectedImage.setVisibility(View.INVISIBLE);
        viewHolder.showSelectedImage.setSelected(true);
        viewHolder.seasonNumber = (TextView) convertView.findViewById(R.id.ondemand_grid_item_season);
        viewHolder.seasonNumber.setVisibility(View.INVISIBLE);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    final OnDemandItem onDemandItem = getItem(position);
    imageLoader.DisplayImage(onDemandItem.getPosterUrl(), viewHolder.image, onDemandItem.getGenrePlaceHolder());
    showHideTrailerIcon(viewHolder, onDemandItem);
    if (onDemandItem.getType() == AssetTypeEnum.SERIE) {
        if (onDemandItem.getSeasonNumber() != null && !"".equals(onDemandItem.getSeasonNumber())) {
            viewHolder.seasonNumber.setVisibility(View.VISIBLE);
            viewHolder.seasonNumber.setText("Seizoen " + onDemandItem.getSeasonNumber());
        }
    }
    viewHolder.title.setText(onDemandItem.getTitle());

    if (selectedOndemandItemId == onDemandItem.getId()) {
        convertView.findViewById(R.id.ondemand_grid_item_img).setVisibility(View.VISIBLE);
    } else {
        ImageView showSelectedImage = (ImageView) convertView.findViewById(R.id.ondemand_grid_item_img);
        if (showSelectedImage != null) {
            showSelectedImage.setVisibility(View.INVISIBLE);
        }
    }

    return convertView;
}`

其中:imageLoader.DisplayImage(onDemandItem.getPosterUrl(),viewHolder.image,onDemandItem.getGenrePlaceHolder()); 是图像异步下载方法


我以前有同样的问题。 这里是我的伪代码解决方案(我使用monodroid,所以不知道它如何在java中工作,但算法应该清楚)

public override View GetView (int position, View convertView, ViewGroup parent)
{
   View v = convertView;

   int rev = 0;
   lock(imageSync){
     if(v == null){
        LayoutInflater vi = (LayoutInflater)Context.GetSystemService (Context.LayoutInflaterService);
        v = vi.Inflate (_textViewResourceId, null);
     }

     rev = Math.Random();
     v.Tag = rev;
   }

   ImageView im = (ImageView)v.FindViewById (R.Id.image_view);
   if (im != null) {
      im.SetImageResource(R.Drawable.loading);
      ImageLoader loader = GetLoader();
      loader.OnImageLoadedListener=delegate (Drawable image, int backRev){
            lock(imageSync){
               if(((int)v.Tag) != backRev) return;
               else im.SetImage(image);
            }
      };
      loader.LoadImage(imageUrl, rev);
   }
}

所以,每当适配器要求我输入数据时,我都会用随机修订号标记视图。 当我使用延迟加载时,我将这个数字传递给加载器,这会在加载过程中保持它。 加载完成后,我比较当前视图修订版和修订版,由加载器返回。 如果他们是平等的,没关系,我设置图像。 如果没有,这意味着在加载期间,用户滚动我的ListView(GridView)和当前View是另一个视图,而不是一个请求图像进入视图的视图。 如果我将图像设置为它,我会用一个图像替换图像,所以我简单地忽略了这种情况。


尝试使用setTag方法以及imageview,我的解决方案像这样工作,在适配器的getView方法中,将setTag设置为正在加载的imageview。

viewHolder.image.setTag(onDemandItem.getPosterUrl()) imageLoader.DisplayImage(onDemandItem.getPosterUrl(), viewHolder.image, onDemandItem.getGenrePlaceHolder());

在imageLoader类中,在附加加载到imageview的位图之前,检查imageview的getTag和url是否传递给加载器类。


我用两个hashmaps解决了这个问题。 视图呈现包含项目以及相应的convertView对象的地图。 您需要确保传入的OnDemandItem项目上有唯一的ID,可用于键入hashmaps。

因此重新编写代码:

//class variables
private HashMap<String, ViewHolder> mapDemandItems = new HashMap<>();
private HashMap<String, View> mapConvertView = new HashMap<>();

public View getView(int position, View convertView, ViewGroup parent) {
OnDemandItem onDemandItem = getItem(position);
viewHolder = mapDemandItems.get(onDemandItem.getId());

if (viewHolder == null) {
    viewHolder = new ViewHolder();
    convertView = layoutInflater.inflate(R.layout.ondemand_grid_item,
            null);

    //set viewHolder values

    mapDemandItems.put(onDemandItem.getId(), viewHolder);
    mapConvertView.put(onDemandItem.getId(), convertView);
} else {
    return mapConvertView.get(onDemandItem.getId());
}

...

return convertView;

}

链接地址: http://www.djcxy.com/p/91307.html

上一篇: getView of ArrayAdapter inconsistent with image downloading

下一篇: view in GridView can be focused, but it doesn't call onFocusChange() method