1

要素が を含むおよび にGridView基づいているがあります。FrameLayout の xml ファイルは次のとおりです。FrameLayoutImageViewCheckedTextView

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

私のアクティビティ クラスでは、コンテキスト メニューをロードし、オプションを選択したら、その要素を次のようにCheckedTextView表示します。GridView

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

したがって、この時点から次の 2 つのことが潜在的に発生する可能性があります。

1)位置0の要素を選択すると、CheckedTextViewが表示されますが、GridViewを下にスクロールすると、別の要素(位置17など)にもCheckedTextViewが表示されます。これは、下に向かって下にスクロールすると、ランダムな要素で続きます。

2) 下に向かって要素を選択し、上にスクロールして戻り、いずれかのメソッドを実行してすべての CheckedTextView を非表示にするNullPointerExceptionと、下の要素に対して a がスローされます。これはView selected =gridView.getChildAt(position);、selected が null になる時点で発生します。

何が起きてる?これらのランダムな CheckedTextView が表示されるのはなぜですか? また、例外が発生するのはなぜですか?

4

1 に答える 1

1

問題は、チェック済みアイテムを追跡する方法にあります。

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コンテンツまでスクロールし、アダプターの位置でインデックスを作成している場合、正しいビューが表示されません。GridViewまたはでアクティブなビューを参照するときは、次のListViewようにします。

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

その理由は、GridView現在表示されているアダプター項目の子ビューのみを保持するためです。要素 0 から 3 が上からスクロールされた場合、要素 4 から 23 の子ビューのみを持つことができます。

これが、その位置のビューを実行すると例外が発生する理由でありView selected =gridView.getChildAt(position);、画面外にある場合は実際には存在しないため、 がgetChildAt返されますnull

2)ListViewまたはGridViewのコンテンツが変更された場合、または子ビューを再レイアウトする必要がある場合は、convertViewパラメーターを使用して既存のビューをアダプターに再バインドします。アダプターは項目ビューのチェック状態を調整しないため、後でチェックを外す必要がある項目にチェック済みビューを再利用できます。

これを解決するには、アイテム ビューに依存するのではなく、アダプターが提示するデータ モデルでアイテムのチェック状態を追跡する必要があります。これは、アダプタが常にアイテムのチェック状態を確認/設定する必要があることを意味します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);
}

次に、アイテムのチェック状態を変更するオプションが選択されたら、上記のコード スニペットの代わりに次のようにします。

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

notifyDataSetChanged()GridViewアイテムビューを再バインドする必要があることを に伝えます。これにより、getViewメソッドがチェック済みの状態を適切に修正します。

于 2011-05-01T20:29:55.587 に答える