android - 为什么我的 CheckedTextView 图标跳转到我的 GridView 中的不同元素?

标签 android gridview imageview checkedtextview

我有一个 GridView,其元素基于包含一个 ImageView 和一个 CheckedTextViewFrameLayout。 FrameLayout 的 xml 文件如下:

<FrameLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:id="@+id/gridImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="false">
</ImageView>
<CheckedTextView
android:id="@+id/imageTick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal|bottom"
android:checkMark="@drawable/icon"
android:checked="false"
android:visibility="invisible"
>
</CheckedTextView>
</FrameLayout>

编辑:这是我为每个元素使用的适配器的 getView() 方法:

public View getView(int position, View convertView, ViewGroup parent) {
        Log.d("getView()", position+"");
        View v;
        ImageView imageView;
        if(convertView == null) {

            v = LayoutInflater.from(mContext).inflate(R.layout.photo_text_view, null);
            v.setLayoutParams(new GridView.LayoutParams(100,100));
        }
        else
        {
            v = convertView;

        }
        imageView = (ImageView) v.findViewById(R.id.image);
        imageView.setImageBitmap(mThumbsIds.get().get(position));

        v.setPadding(8, 8, 8, 8);
        return v;
    }

在我的 Activity 类中,我加载了一个上下文菜单,一旦我选择了一个选项,我就使该 GridView 元素的 CheckedTextView 可见,如下所示:

GridView gridView = (GridView) findViewById(R.id.gridview);
    View selected =gridView.getChildAt(position);
    CheckedTextView selectedCheck = (CheckedTextView)selected.findViewById(R.id.imageTick);
    selectedCheck.setChecked(true);
    selectedCheck.setVisibility(View.VISIBLE);

因此从这一点开始可能会发生两件事:

1) 假设我选择了位置 0 处的元素,CheckedTextView 变得可见,但是当我向下滚动 GridView 时,另一个元素(例如位置 17)的 CheckedTextView 也可见。当我向下滚动到底部时,这会继续出现在随机元素上。

2) 如果我选择底部的元素,向上滚动到顶部,并运行其中一种方法使所有 CheckedTextView 不可见,则会为底部的元素抛出 NullPointerException。这发生在此时:View selected =gridView.getChildAt(position); where selected 变为 null。

这是怎么回事?为什么这些随机的 CheckedTextView 变得可见,为什么我会得到异常?

最佳答案

问题在于您跟踪托运项目的方式:

GridView gridView = (GridView) findViewById(R.id.gridview);
View selected =gridView.getChildAt(position);
CheckedTextView selectedCheck = (CheckedTextView)selected.findViewById(R.id.imageTick);
selectedCheck.setChecked(true);
selectedCheck.setVisibility(View.VISIBLE);

1) getChildAt 如果您滚动到内容中并且您正在按适配器位置编制索引,则不会为您提供正确的 View 。在 GridViewListView 中引用 Activity View 时,您需要执行如下操作:

final int index = position - gridView.getFirstVisiblePosition();
View selected = gridView.getChildAt(index);

原因是您的 GridView 只保留当前显示的适配器项的 subview 。如果元素 0 到 3 较早地滚出顶部,它可能只有元素 4 到 23 的 subview 。

这就是为什么当您执行 View selected =gridView.getChildAt(position); 时会出现异常的原因,该位置的 View 在屏幕外时实际上并不存在,因此 getChildAt 返回 null

2) 当 ListViewGridView 的内容发生变化或需要重新布局其 subview 时,它通过使用重新绑定(bind)现有 View 来实现convertView 参数到您的适配器。您的适配器从不调整项目 View 的选中状态,因此选中的 View 可以重新用于以后应该取消选中的项目。

要解决这个问题,您应该让您的适配器呈现的数据模型跟踪项目的检查状态,而不是依赖项目 View 来执行此操作。这意味着您的适配器应始终在 getView 中验证/设置项目的选中状态。它可能看起来像这样:

imageView = (ImageView) v.findViewById(R.id.image);
imageView.setImageBitmap(mThumbsIds.get().get(position));

CheckedTextView checkView = (CheckedTextView) v.findViewById(R.id.imageTick);

if (mData.isItemChecked(position)) {
    checkView.setChecked(true);
    checkView.setVisibility(View.VISIBLE);
} else {
    checkView.setVisibility(View.GONE);
}

然后当您选择应该更改项目的选中状态的选项时,而不是上面的代码 fragment 执行如下操作:

data.setItemChecked(position, true);
adapter.notifyDataSetChanged();

notifyDataSetChanged() 将告诉 GridView 它应该重新绑定(bind)项目 View ,这将使您的 getView 方法修复正确检查状态。

关于android - 为什么我的 CheckedTextView 图标跳转到我的 GridView 中的不同元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5850456/

相关文章:

c# - 打开一个包含来自 gridview 单元格的详细信息的 ajax modalpopup

java - Android - 将 ImageView 设置为 URL

java - ImageView 导致延迟

java - 插入的行实际上并未插入

java - 可视化 Java 项目

Android gridview,如何去除网格项之间的间隙

android - 如何在android中制作圆角半径

android - 应用启动后 Imageview 可见 3 秒

android - 谷歌地图,带有 admin lte 、 android 和 IOS

java - 尝试启动 fragment 时应用程序强制关闭