8

複数回呼び出された getView の問題とすべての回答について読みました。ただし、問題の解決策が見つかりません。

行に 2 つの状態があるリストがあります: 読み取りまたは非読み取り。さて、初めて見たアイテムを別の色にしたいのですが、リストをスクロールすると、色が「読み取り状態」に変わります。

これを行うために、アダプターのメソッド getView で、そのアイテムの行が描画されるときにフィールド isRead を設定します。しかし、問題は次のとおりです。メソッド getView が複数回呼び出されるため、フィールドは既読としてマークされ、リストが画面に表示されると、すでに読まれたように見えます。

この問題を解決するアイデアはありますか?

ありがとう

4

4 に答える 4

14

getView が同じビューを数回要求する問題を意味していると思います。

ListView は、さまざまな理由 (スクロールバーのサイズ、レイアウトなど) でビューの測定値を取得する必要があるため、これを行います。

この問題は通常、リストビューで「wrap_content」プロパティを使用しないことで回避できます。

それ以外では、 getView を使用してビューが表示されているかどうかを判断することは、単に悪い考えです。ListView には、行ごとに getView が呼び出される順序を混乱させる多くの最適化が含まれているため、何が起こるかを知る方法がなく、アプリが奇妙な動作を示し始めます。

そのデータの表示としてのビューの概念以外のビューとデータの間の関係を避けるようにしてください。

代わりに、リスト内のアイテムがユーザーに表示されたリストを監視し、データを更新し、アダプタで dataSetChanged を呼び出す listactivity の一部のワーカー スレッドまたはイベント リスナーを使用します。

于 2010-07-07T15:46:36.517 に答える
1

同じ問題があり、レイアウト属性の「wrap_content」への参照がまったくありませんでした。これは古いスレッドですが、問題を解決する方法がわかりませんでした。したがって、以下のコードに示すように、既に描画された位置を保持するアダプターにリストを追加することで、それを軽減しました。それはすぐにできることではないと思いますが、私にとってはうまくいきました。

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private List<Integer> usedPositions  = new ArrayList<Integer>();

    public ImageAdapter(Context c, List<String> imageUrls) {
        mContext = c;
        ...
    }

    ...

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) { 
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }

        if (!usedPositions.contains(position)) {
            // Your code to fill the imageView object content
            usedPositions.add(position); // holds the used position
        }

        return imageView;
    }
}
于 2011-03-28T18:23:04.910 に答える
0

このコード ブロックの下に何もレイアウトが歪まないことがわかっている場合に、二重呼び出しを回避するための非常に簡単な方法を次に示します。

private static List<String> usedPositions  = new ArrayList<String>();

...

@Override
public View getView(int position, View rowView, ViewGroup parent) {
    rowView = inflater.inflate(R.layout.download_listview_item, null);

    Log.d(LOG_TAG, "--> Position: " + position);

    if (!usedPositions.contains(String.valueOf(position))){
        usedPositions.add(String.valueOf(position));
        return rowView;
    }else{
        usedPositions.remove(String.valueOf(position));
    }

...

于 2011-12-11T20:26:12.853 に答える
0

あなたが望む方法ではありません。複数回呼び出される理由getView()は、OS が行を測定できるようにして、行の配置方法を認識できるようにするためです。クリックしたり、ボックスなどにチェックを入れたりしたときに、既読としてマークする必要があります。

于 2010-07-07T15:46:10.007 に答える