1

我有一个 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>

谢谢你。

4

1 回答 1

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 的性能。您可以观看这个精彩的演示文稿以获取更多信息。

于 2013-08-08T02:47:51.487 回答