Android TextView setText不起作用,但setTextColor确实有效吗?

时间:2013-08-25 10:20:30

标签: android listview android-fragments

我在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模拟器上,问题不会发生,颜色和文字都会发生变化......

5 个答案:

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

这可以很容易地扩展到存储多个标记项目,其他元数据等。