CheckedTextViewアイコンがGridViewのさまざまな要素にジャンプするのはなぜですか?

StackOverflow https://stackoverflow.com/questions/5850456

質問

私は持っています GridView その要素はaに基づいています FrameLayout を含む ImageView そしてa CheckedTextView. 。 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;
    }

アクティビティクラスでは、コンテキストメニューをロードし、オプションを選択したら 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の目に見えないようにする方法の1つを実行します。 NullPointerException 下部の要素のために投げられます。これはこの時点で起こります: View selected =gridView.getChildAt(position); 選択した場所は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 コンテンツにスクロールしてアダプターの位置でインデックスを付けている場合、正しいビューは表示されません。でアクティブビューを参照する場合 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)a 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 メソッドチェック状態を適切に修正します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top