2

頻繁に更新されるAndroidListViewがあります。リスト内のアイテムをクリックすると、間違ったオブジェクトがクリックイベントを取得する時間のサブセットがあります。これは、更新によってリストが変更されない場合でも発生します。

これを間違ってコーディングしているだけですか、それともビュー階層を介したイベント処理に競合状態がありますか?

ListViewは、BaseAdapterを拡張するアダプターを使用し、そのgetView()メソッドは次のようになります。ただし、この問題はUSE_LAYOUT=trueの場合にのみ発生します。

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

    if (convertView == null) {
        if (USE_LAYOUT) {
            view = context.getLayoutInflater().inflate(R.layout.row, parent, false);
            textView = (TextView) view.findViewById(R.id.rowTextView);
        } else {
            view = new TextView(context);
            textView = (TextView) view;
        }
        viewHolder = new ViewHolder();
        viewHolder.textView = textView;
        view.setTag(viewHolder);
    } else {
        view = convertView;
        viewHolder = (ViewHolder) view.getTag();
        textView = viewHolder.textView;
    }

    final String item = getItem(position);
    textView.setText(position + " " + item);
    textView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("Adapter", position + " " + item);
        }
    });

    return view;
}

したがって、上記のコードに関しては、アクティビティは「1 item1」、「2 item2」、「3 item3」などを示すリストビューを表示します。たとえば、item3をクリックすると、ログに表示されます。 「21item21」。

コードに関する他のいくつかのポイント:

  • アイテムは単なる文字列であり、アダプタはを維持しList<String>getItem()を呼び出すだけで、リストを設定してを呼び出しitems.get(index)ます。setItems()notifyDataSetChanged()
  • リストを変更しないと問題が発生します。つまり、タイマーはを呼び出しますsetItems(new ArrayList<String>(getItems())
  • setItems()UIスレッドから。を介して呼び出されますrunOnUiThread()
  • タイマーは約500msごとにオフになりますが、他の周波数で問題が発生します。
  • 行レイアウトは、LinearLayout内の単なるTextViewです。

ビューがgetViewを介してリサイクルされると、逆の順序でリサイクルされることを確認しました。つまり、notifyDataSetChanged()が呼び出されてリストがスクロールされていない場合、最初のアイテムは最後のアイテムと一緒にリサイクルされ、2番目のアイテムは最後から2番目のアイテムと一緒にリサイクルされます。また、私は2.1と2.3でそれを観察しますが、4.0では観察しません(私はそれがそこで決して起こらないかどうかはわかりませんが)。

4

1 に答える 1

0

問題は、メソッド内のコードonClick()が実行時とは異なる時間にgetView()実行されるため、positionおそらく期待どおりではないことです...これを試してください:

final String item = getItem(position);
textView.setTag(position);
textView.setText(position + " " + item);
textView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        int position = (Integer) v.getTag();
        Log.d("Adapter", position + " " + getItem(position));
    }
});

言い換えれば、内部のすべてのものは内部のローカル変数をnew OnClickListener() { ... }見ることができません( や のように) が、クラス変数とメソッド ( のように)を見ることができます。getView()positionitemgetItem()

于 2012-09-29T19:03:28.577 に答える