Android GridView项目选择器更改位置和重复

时间:2013-08-08 01:00:43

标签: android gridview selector adapter

我有一个GridView布局,包含3列和几行,其中包含从Facebook获取的图片。当我选择图像时,正常情况下会在gridView中为该项目显示一个选择器。 (我不使用android选择器,而是使用下面链接的自定义布局。)

问题在于:如果我选择一个或多个项目,当我向下滚动屏幕以查看更多图片时,我发现其他项目已被选中!此外,如果我向上滚动以查看我之前选择的项目,选择器会更改其位置。在我看来,每次滚动屏幕时每个选择器的索引都会更新。

我创建了一个个人的ImageAdapter来为Facebook上的图片充气。 这里是getView:

public View getView(final int position, View convertView, ViewGroup parent) {

        View v;
        ImageView imageView = null;
        if(convertView==null){
            LayoutInflater li = getLayoutInflater();
            v = li.inflate(R.layout.photos_item, null);
        }else{
            v = convertView;
        }     
        imageView = (ImageView)v.findViewById(R.id.image);
        v.setTag(imageView);
        if (arrayPhotos.get(position).getPictureSource() != null){
            Log.i(TAG, "Position in GridView = " + Integer.valueOf(position).toString());
            imageLoader.DisplayImage(arrayPhotos.get(position).getPictureSource(), imageView);
        }
        return v;

    }

这里的onItemClick:

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

View checkedItem;

    checkedItem = (View) view.findViewById(R.id.check);

    fbPicture = arrayFbPictures.get(position);
    Log.i(TAG, "Position = " + arrayFbPictures.indexOf(fbPicture));
    Log.i(TAG, "PicId = " + fbPicture.getPictureID());

    if( fbPicture.isChoosed() ){

        Log.i(TAG, "checkIcon DISACTIVATED");
        fbPicture.setChoosed(false);
        checkedItem.setVisibility(View.INVISIBLE);
        parent.invalidate();
    }
    else{

        Log.i(TAG, "checkIcon ACTIVATED");
        fbPicture.setChoosed(true);
        checkedItem.setVisibility(View.VISIBLE);
        parent.invalidate();
    }
}

这是GridView的xml:

<GridView
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="center"
    android:gravity="center"
    android:numColumns="auto_fit" 
    android:columnWidth="96dp"
    android:stretchMode="spacingWidth"
    android:horizontalSpacing="8dp"
    android:verticalSpacing="8dp"
    android:paddingTop="8dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp" >
</GridView>

这是自定义选择器的xml:

<RelativeLayout
   android:id="@+id/check"
   android:layout_width="96dp"
   android:layout_height="96dp"
   android:background="@color/black_trasparency_light"
   android:visibility="invisible" > 

    <ImageView
        android:id="@+id/image_check"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:scaleType="center"
        android:src="@drawable/ic_check_colored_48" />

</RelativeLayout>

谢谢。

1 个答案:

答案 0 :(得分:0)

发生这种情况的原因是因为GridView使用视图回收。当您向下滚动GridView时,GridView不会创建新视图以放在底部,而是重用从顶部消失的那些视图。这意味着您必须记住在调用getView()时完全设置视图的状态。

这有点难以消化,所以这里有一些代码:

public View getView(final int position, View convertView, ViewGroup parent) {
  ...

  View checkedItem = (View) v.findViewById(R.id.check);

  fbPicture = arrayFbPictures.get(position);
  if (fbPicture.isChoosed()) {
     checkedItem.setVisibility(View.VISIBLE);
  } else {
     checkedItem.setVisibility(View.INVISIBLE);
  }

  return v;
}

上面的代码是每次调用getView()时都设置convertView的检查状态,因此循环视图不会保留任何先前的状态。

PS。这样做是为了节省内存并提高GridView和ListView的性能。您可以观看这个很棒的presentation以获取更多信息。