ListView
试图通过回收其适配器生成的视图来提高效率,而不是总是创建新视图。在 的情况下CursorAdapter
,该方法hasStableIds()
返回true
让列表知道重用视图是安全的。
当列表的布局发生变化时,无论是因为底层数据模型发生了变化,还是因为列表视图的位置或大小发生了变化,表示项目的视图都将被重用。这就是颜色得以保留的原因——它View
和以前一样!但是,当CursorAdapter.bindView()
准备显示视图时,它会setText(...)
使用光标中的数据进行调用,从而恢复原始文本并覆盖您的更改。它不调用setTextColor()
,这就是保留文本颜色的原因。除非您将视图从屏幕上滚动并返回,在这种情况下,视图将被回收并且所有更改都将丢失。
TL;博士
要解决此问题,您可以使用自定义SimpleCursorAdapter
来跟踪标记的项目并在重新绑定视图时执行一些特殊操作。您也可以使用ViewBinder
.
private MySimpleAdapter mMySimpleAdapter;
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mMySimpleAdapter.markItemWithId(id);
}
private static class MySimpleAdapter extends SimpleCursorAdapter {
private long mMarkedId = AdapterView.INVALID_ROW_ID;
...
public void markItemWithId(long id) {
mMarkedId = id;
// Let the list know that something changed and
// it needs to update the displayed views.
notifyDataSetChanged();
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
// Give the marked view special treatment.
if (mMarkedId != AdapterView.INVALID_ROW_ID) {
final long rowId = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
if (rowId == mMarkedId) {
// Set color, text, etc.
...
}
}
}
}
这可以很容易地扩展到存储多个标记项目、附加元数据等。