4

我将 SimpleCursorAdapter 与一个 xml 文件一起使用,其中定义了一些视图:

<LinearLayout ...>
    <ImageView android:id="@+id/listIcon" />
    <TextView android:id="@+id/listText" />
</LinearLayout>

我的目标是以编程方式设置 TextView 的文本颜色和 LinearLayout 的背景颜色(即 ListView 中的每一行);颜色是从数据库返回的。

例如,当我在没有抱怨的情况下发现它之后,我在尝试操纵 TextView 时遇到了 NPE:

TextView tv = (TextView) findViewById(R.id.listText);
tv.setTextColor(color); // NPE on this line

这是公平的;如果列表中有多个条目,则可以合理地假设“ R.id.listText ”将不起作用。所以我扩展了 SimpleCursor Adapter:

public View getView(int position, View convertView, ViewGroup parent) {
    View row = super.getView(position, convertView, parent);
    TextView text = (TextView) row.findViewById(R.id.listText);
    // ImageView icon = (ImageView) row.findViewById(R.id.listIcon);

    // If there's an icon defined
    if (mIcon_id != 0) {
        // icon.setImageResource(mIcon_id);
    }

    // If text color defined
    if (mTextColor != 0) {
        text.setTextColor(mTextColor);
    }

    // If background color set
    if (mBackgroundColor != 0) {
        row.setBackgroundColor(mBackgroundColor);
    }
    return(row);
}

我得到两个不同的错误:

  • 在“ text.setTextColor(mTextColor) ”处引发了类似的 NPE
  • 如果带有 ImageView 的行未注释,我会得到一个“ ClassCastException: android.widget.TextView ”,我正在调用“ row.findViewById(R.id.listIcon)

作为参考,我试图使用 Commonsware 的示例代码,并将其应用于我的情况。链接 (pdf)


改为:

public View getView(int position, View convertView, ViewGroup parent) {
    convertView = super.getView(position, convertView, parent);

    if (convertView == null) convertView = View.inflate(mContext, R.layout.theme_item, null);
    TextView text = (TextView) convertView.findViewById(R.id.listText_tv);
    ImageView icon = (ImageView) convertView.findViewById(R.id.listIcon_iv);

    // If there's an icon defined
    if (mIcon_id != 0) {
        icon.setImageResource(mIcon_id);
    }

    // If text color defined
    if (mTextColor != 0) {
        text.setTextColor(mTextColor);
    }

    // If background color set
    if (mBackgroundColor != 0) {
        convertView.setBackgroundColor(mBackgroundColor);
    }
    bindView(convertView, mContext, mCursor);
    return(convertView);
}

现在我在下一个活动中得到一个 ClassCastException(单击列表项)。在下一个活动中没有任何修改;它在对具有条目的列表使用 SimpleListAdapter 时起作用(单击该列表会导致 Activity2),所以我认为在这个扩展类中我仍然做错了。

4

4 回答 4

5

convertView永远是一个现有的实例是不正确的。你应该检查它是否为空,然后实例化它。如果没有,您可以像以前一样更改它。

这应该是这样的:

public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null)
        convertView = //inflate your row here
    View row = convertView;
    //Manipulate the row here
    return(row);
}
于 2011-03-14T20:38:58.677 回答
1

我会修改 getView 方法:

public View getView(int position, View convertView, ViewGroup parent) {
    convertView = View.inflate(getContext(), R.layout.myLayout, null);
    TextView text = (TextView) convertView.findViewById(R.id.listText);
    ImageView icon = (ImageView) convertView.findViewById(R.id.listIcon);

    // If there's an icon defined
    if (mIcon_id != 0) {
      icon.setImageResource(mIcon_id);
    }

    // If text color defined
    if (mTextColor != 0) {
      text.setTextColor(mTextColor);
    }

    // If background color set
    if (mBackgroundColor != 0) {
      convertView.setBackgroundColor(mBackgroundColor);
    }

    return convertView;
}
于 2011-03-14T21:28:29.833 回答
0

我认为您正在获得 NPE,因为您试图在它们不存在的视图中创建一个 textview 和一个 imageview。

当您想使用来自数据库的条目来扩充 ListView 时,在您的活动中,您可以使用 ListView 定义 main.xml:

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/listView1">
</ListView>

并在 onCreate 方法中使用setContentView(R.layout.main);. 然后你创建你的光标到你的数据库和你的自定义适配器:

    MySimpleCursorAdapter adapter = new MySimpleCursorAdapter(this, R.layout.entry,
                names, new String[] {Phones.NAME, Phones.NUMBER}, new int[] {
                R.id.listIcon, R.id.listText});
    startManagingCursor(cursor);
    ListView listView = (ListView) findViewById(R.id.listView1);
    listView.setAdapter(adapter);

然后你用你的listIcon和listText定义一个entry.xml,适配器指向的地方。在我的示例中,我正在从联系人列表中查询姓名和号码。

在您的自定义适配器中,您应该可以毫无问题地访问 getView 或 bindView 中的 textview 和 imageview。

在这里 ,您有一个示例来获取联系人列表中的所有联系人及其图片、姓名和号码,但使用 ListActivity 而不是活动,并且只有一个带有两个文本视图和一个图像视图的 xml。如果使用 ListActivity,则不需要使用 ListView,也不需要在 Activity 中设置内容视图。

我希望它有帮助!

于 2011-03-14T21:31:18.767 回答
-2

不要忘记为每个视图添加:layout_width 和 layout_heigth。

于 2011-03-14T20:25:23.040 回答