1

我在 Android Fragment 中有一个 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”。

但是,如果我从我的应用程序中其他地方的代码(不是在片段或回调中)获得对相同文本视图的引用,则两个调用都可以正常工作并且文本更改为“Hello”。

有谁知道为什么 setTextColor 会起作用,但 setText 在回调内部不起作用,但在回调外部都起作用?

谢谢。

编辑:这只发生在我的手机上,即 API 级别 15。在 API 17 模拟器上,问题不会发生,颜色和文本都会改变......

4

5 回答 5

3

您的代码使适配器重新绘制项目。因此,您接到了getView()相同项目的电话。

我猜你在打电话setText()getView()但不是setTextColor()。你正在回收视图。

于 2013-08-28T11:08:21.873 回答
0

我猜你正在设置 textview 文本 2 次,彻底更改为默认文本检查

于 2013-08-25T10:24:53.507 回答
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");

            }
    }
于 2013-08-28T11:27:03.563 回答
0

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.
                ...
            }
        }
    }
}

这可以很容易地扩展到存储多个标记项目、附加元数据等。

于 2013-08-29T04:54:45.850 回答
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());
  }
}

看看会发生什么

于 2013-08-28T11:05:08.103 回答