调用notifyDataSetChanged时,BaseAdapter位置发生了变化

时间:2013-09-13 11:05:10

标签: android listview baseadapter

我有这样的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
谁能告诉我为什么?谢谢,bellow是适配器代码。

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;
}

}

1 个答案:

答案 0 :(得分:0)

无论何时调用notifyDataSetChanged(),都会刷新视图,重新创建或回收,换句话说,将为每个可见行再次调用getView方法。

只有在模型发生变化时才应调用它,在你的情况下 listEntity ,只有在添加了新元素或者列表中已有元素的数据发生变化时才会调用它。

如果你要膨胀2种不同的布局,请注意使用实现方法getItemViewType()和getViewTypeCount()这将保证getView()方法给出的给定'convertView'参数对应于你的那个应该用于给定的位置。所以在你的情况下,尽管代码似乎不完整,但我认为由于这个问题你正在接收被回收的位置的错误convertView参数,这就是为什么你在日志中有不同的id。