1

Android でカスタム作成された CursorAdapter 派生クラスに奇妙な問題があります。

私の getView() の実装は、多くのサイトや Google トークで見られる教科書そのものです。ただし、異なる位置(このメソッドが呼び出される位置パラメーター) については、このメソッドにはconvertViewの同じインスタンスが渡されているようですが、私が見ているように、これらは異なるオブジェクトインスタンスを参照する必要があります。 ListView 内の他の可視アイテム。可視リスト アイテムの場合は、同じオブジェクト インスタンスを再利用しないでください。

実際のビューを更新する実際の部分は、それがなくても問題が再現されるため、削除しました。

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;

        Log.d("dd", "getView()");

        if (convertView == null) {
            Log.d("d", "convertview is null!");

            // create convertView from xml
            convertView = this.mInflater.inflate(R.layout.catalog_entry,
                    parent, false);

            // create the viewHolder
            viewHolder = new ViewHolder();

            viewHolder.name = (TextView) convertView
             .findViewById(R.id.gameName2);
             viewHolder.image = (ImageView) convertView
             .findViewById(R.id.gameImage);

            convertView.setTag(viewHolder);
        } else {
            Log.d("dd", "convertview is not null");
            viewHolder = (ViewHolder) convertView.getTag();
        }

        LinearLayout thisItem = (LinearLayout) convertView;
        Log.d("thisItem",
                "This Item is Index "
                        + position
                        + " "
                        + thisItem.toString()
                        + " "
                        + Integer.toHexString(System.identityHashCode(thisItem))
                        + "x: " + thisItem.getX() + " y: " + thisItem.getY());

        this.cur.moveToPosition((int) (getItemId(position) - 1));

        Log.d("dd", "End of getView()");
        return convertView;
    }

このコードを実行すると、次の出力が生成されます。

D/dd (27725): getView() D/d (27725): convertview が null です! D/thisItem(27725): このアイテムはインデックス 0 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725): getView() D/dd
(27725): convertview は null ではありません D/thisItem(27725): このアイテムはインデックス 1 です android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725 ): getView() D/dd
(27725): convertview は null ではありません D/thisItem(27725): このアイテムはインデックス 2 です android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): 終わりgetView() D/dd (27725): getView() D/dd
(27725): convertview は null ではありません D/thisItem(27725): このアイテムはインデックス 3 です android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725 ): getView() D/dd
(27725): convertview は null ではありません D/thisItem(27725): このアイテムはインデックス 4 です android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): 終わりgetView () D/dd (27725): getView() D/dd
(27725): convertview は null ではありません D/thisItem(27725): このアイテムはインデックス 0 です android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D /dd
(27725): getView() の終わり D/dd (27725): getView() D/d
(27725): convertview が null です! D/thisItem(27725): このアイテムはインデックス 1 です android.widget.LinearLayout@40fb89f8 40fb89f8x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725): getView() D/d
(27725): convertview が null です! D/thisItem(27725): このアイテムはインデックス 2 android.widget.LinearLayout@40fb9c48 40fb9c48x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725): getView() D/d
(27725): convertview が null です! D/thisItem(27725): このアイテムはインデックス 3 です android.widget.LinearLayout@40fbae98 40fbae98x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり D/dd (27725): getView() D/d
(27725): convertview が null です! D/thisItem(27725): このアイテムはインデックス 4 です android.widget.LinearLayout@40fbc0e8 40fbc0e8x: 0.0 y: 0.0 D/dd
(27725): getView() の終わり

最初に、各位置 (0 から 4) に対して、同じ View オブジェクト ハッシュが送信されていることがわかります...

4

2 に答える 2

4

つまり、ListViewの高さをmatch_parentまたは別の固定の高さに設定します。

ListViewが「ドライラン」方式で呼び出す理由はたくさんありますがgetView()、最も一般的なのはwrap_content、ListViewの高さとして使用したためです。Androidは、の高さを計算するために一連の行を膨らませる必要がありwrap_contentますが、これはまだ利用できないため、実際のデータを使用することはできません。したがって、アダプタはこれらの最良の推測を破棄します。後でレイアウトが実際のデータで(再)作成されるため、各行が2回作成されます。

また、CursorAdapterは適切な行自体を維持する必要があります。次の行は必要ありません。

this.cur.moveToPosition((int)(getItemId(position) - 1));
于 2013-03-05T21:34:36.567 に答える
1

ビューが によって再利用されるのは正しいことConvertviewです。すべてのパーツを削除することができ、Convertview望ましくないビューを再利用することはなく、目的の結果が得られます (パフォーマンスがいくらか犠牲になります...)。

于 2013-03-05T20:15:56.837 に答える