-1

我有一个像这样的 BaseAdapter。比方说,我只有四行。

我将使用 posttion 为这四个 convertView 调用 setId 。我将在某处调用 notifyDataSetChanged() (我在顶部定义一个按钮,单击该按钮将调用 notifyDataSetChanged),当调用 notifyDataSetChanged 时,四行将由 getView() 调用。在 getView() ,我将打印 id(旧位置)和新位置。由于行没有变化,我认为位置不会改变。他们将是相同的。但事实并非如此。

打印:

D/BasePhotoFragment(19230): position:0
D/BasePhotoFragment(19230): old id :3
D/BasePhotoFragment(19230): new id :0
D/BasePhotoFragment(19230): position:1
D/BasePhotoFragment(19230): old id :2
D/BasePhotoFragment(19230): new id :1
D/BasePhotoFragment(19230): position:2
D/BasePhotoFragment(19230): old id :1
D/BasePhotoFragment(19230): new id :2
D/BasePhotoFragment(19230): position:3
D/BasePhotoFragment(19230): old id :0
D/BasePhotoFragment(19230): new id :3

谁能告诉我为什么?谢谢,下面是适配器代码。

public class PhotosGridAdapter extends BaseAdapter{

private LayoutInflater mInflater;
private Context mContext ;
private List<PhotoEntity> listEntity ;
private int mLinePhotos;
private LinearLayout.LayoutParams mphotoParams = new android.widget.LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);

private final class ViewHolder{
    public List<ImageView> imgs;
}

public PhotosGridAdapter(Context ctx,List<PhotoEntity> entities) {
    this.mContext = ctx ;
    mInflater = LayoutInflater.from(ctx);
    mLinePhotos = Utils.getPhotosNumOfLine(ctx);
    listEntity = entities;
}

@Override
public int getCount() {
    return listEntity != null ? listEntity.size() / mLinePhotos  : 0;
}

@Override
public Object getItem(int position) {
    if( position < listEntity.size() )
    return listEntity.get(position);
    else
    return null;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Log.d(TAG,"position:"+position);
    ViewHolder holder = null;

    if (convertView == null) {
    holder = new ViewHolder();
    convertView = mInflater.inflate(R.layout.row_grid_photos_container, null);
            ....
    convertView.setTag(holder);
    }else{
    holder = (ViewHolder)convertView.getTag();
    }


   int old_id = convertView.getId();

   Log.d(TAG,"old id :"+old_id);
   Log.d(TAG,"new id :"+position);

   if(old_id == position)
       return convertView;

       convertView.setId(position);

       ..... do some bind .
   return convertView;
}

}

4

1 回答 1

0

每当您调用 notifyDataSetChanged() 时,视图都会被刷新,无论是重新创建还是回收,换句话说,每个可见行都会再次调用 getView 方法。

您应该仅在模型发生更改时调用它,在您的情况下为 listEntity,仅当向其中添加了新元素或列表中已有元素的数据已更改时才调用它。

如果您正在膨胀 2 个不同的布局,请注意使用实现方法 getItemViewType() 和getViewTypeCount()这将保证 getView() 方法上给出的给定 'convertView' 参数对应于您应该用于给定的位置。所以在你的情况下,虽然代码看起来不完整,但我相信你收到了错误的 convertView 参数来回收位置,由于这个问题,这就是为什么你在日志中有不同的 id。

于 2013-09-13T11:17:10.533 回答