我在Android片段中有一个ListView,并在行中填充了SimpleCursorAdapter。片段本身被设置为ListView的OnItemClickListener。
单击某个项目时,将运行以下代码:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(R.id.title);
textView.setTextColor(Color.RED);
textView.setText("Hello");
}
文本颜色变为红色,但实际文本不会更改为“Hello”。
但是,如果我从应用程序中的其他地方的代码(不在片段或回调中)中引用相同的textview,则两个调用都可以正常工作,文本将更改为“Hello”。
有没有人知道为什么setTextColor可以工作,但是setText在回调中不起作用,但在回调之外都有效?
感谢。
编辑:这只发生在我的手机上,即API级别15.在API 17模拟器上,问题不会发生,颜色和文字都会发生变化......
答案 0 :(得分:3)
您的代码使适配器重绘项目。
因此,您可以为同一项目打电话getView()
。
我猜您在setText()
中呼叫getView()
,而不是setTextColor()
。
而你正在回收这个观点。
答案 1 :(得分:0)
我猜您再次将textview文本设置为2次更改为默认文本检查
答案 2 :(得分:0)
尝试捕获异常
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(R.id.title);
textView.setTextColor(Color.RED);
try {
textView.setText("Hello");
} catch (MyException e){
throw new IOException(e.toString());
}
}
看看会发生什么
答案 3 :(得分:0)
请尝试以下代码。
public void onItemClick(AdapterView<?> parent, View row, int position, long id) {
int diplayPosition= position-parent.getFirstVisiblePosition();
for (int i = 0; i < parent.getChildCount(); i++) {
TextView textView = (TextView)view.findViewById(R.id.title);
textView.setTextColor(Color.RED);
textView.setText("Hello");
}
}
答案 4 :(得分:0)
ListView
尝试通过回收其适配器生成的视图来提高效率,而不是始终创建新视图。在CursorAdapter
的情况下,方法hasStableIds()
会返回true
,这会让列表知道重复使用视图是安全的。
当列表的布局发生更改时,要么是因为基础数据模型已更改,要么是因为列表视图的位置或大小已更改,所以将重用表示项目的视图。这就是保留颜色的原因 - 它和以前一样View
!但是,当CursorAdapter.bindView()
准备要显示的视图时,它会使用光标中的数据调用setText(...)
,从而还原原始文本并覆盖您的更改。它不会调用setTextColor()
,这就是保留文本颜色的原因。除非您将视图从屏幕上滚动并向后滚动,否则视图将被回收并且所有更改都将丢失。
<强> TL; DR 强>
要解决此问题,您可以使用自定义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.
...
}
}
}
}
这可以很容易地扩展到存储多个标记项目,其他元数据等。