頻繁に更新される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では観察しません(私はそれがそこで決して起こらないかどうかはわかりませんが)。