在Listview中更改特定的TextView颜色

时间:2014-10-07 10:44:51

标签: android database listview adapter

我有两个数据库 第一个包含所有项目,ListView显示它 第二个数据库包含收藏项,[从第一个数据库中选择]

我想要的是当listview显示所有项目时 检查该项目是否已存在于Favoritelist中,然后为该项目制作该文本视图背景为红色

我有这个代码可以正常工作

    public static void ChangeMyFavoritesBG(){

for (int i = 0; i < Items.size(); i++)  {

if(db.verification(Items.get(i).toString())){

try {

TextView favtextview = (TextView) listview.getChildAt(i-listview.getFirstVisiblePosition()).findViewById(R.id.item_name);
 favtextview.setBackgroundResource(R.drawable.redcolor);

}catch (NullPointerException e) {

}}}}

db.verification检查收藏夹数据库中是否存在项目 如果是真的 。然后它应该将此项目的背景更改为红色

此代码工作正常,但只有我按下按钮单击 我需要让代码自动运行 但如果我在活动加载时自动启动,我会得到NullPointer错误

我猜是因为函数ChangeMyFavoritesBG();列表视图显示项目之前的工作

任何想法的人?抱歉我的英文不好

2 个答案:

答案 0 :(得分:0)

在listView使用的适配器的getView(int position, View convertView, ViewGroup parent)方法中执行此控制。

答案 1 :(得分:0)

如果您的收藏夹当前在ListView中不可见,则getChildAt()将返回null。

您正在循环查看列表视图中的所有项目,我的猜测是它包含的项目数量超出了屏幕上的数量。如果你喜欢的项目是其中之一,那么你的代码片段

listview.getChildAt(i-listview.getFirstVisiblePosition())

将返回null。当你在其上调用findViewById(R.id.item_name)时,这将导致NullPointerException。

只需在getChildAt()的结果上添加null检查。如果它为null则不执行任何操作,如果它为非null,则调用第二部分。当您喜欢的项目不在屏幕上时,这将防止异常,并且当您的喜爱在屏幕上可见时,将允许它显示为红色。

<强>更新

我很抱歉,我快速阅读并误解了你的问题是关于NullPointerException但你说你的代码在按钮点击处理程序中调用它时工作正常,但在启动时自动调用它时却没有。

你说得对,当你还在onCreate()时,ListView还没有加载任何项目。您可以在运行代码之前添加延迟。以下适用于我:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);

    // initialize the ListView with data for the list items. (I'm using a string array in this 
    // example. You are loading it from a database table, but that is the same in principle.)
    ListAdapter adapter = new ArrayAdapter<String>(this, R.layout.item_list, R.id.item_name, Items);
    ListView listview = (ListView) findViewById(R.id.listview);
    listview.setAdapter(adapter);

    // ask the system to wait before setting the background color of the favorite item so that
    // the ListView has time to load the items.
    final int DELAY_IN_MILLISECONDS = 100;
    listview.postDelayed(new Runnable() {
        @Override
        public void run() {
            ChangeMyFavoritesBG();
        }
    }, DELAY_IN_MILLISECONDS);
}

正如您在上面的示例中所看到的,在初始化ListView之后,您要求系统在调用ChangeMyFavoritesBG()之前等待100毫秒。希望有足够的时间将数据库中的项加载到ListView中。如果时间不够,那么你可以使用更长的延迟。

替代

以上应该有效,但说实话我不会这样写。上面的代码非常脆弱,因为它取决于加载项目所需的时间。我建议您将背景颜色放入自定义适配器中。

因为您希望以自定义方式显示项目 - 您希望它们在最喜欢的项目时具有红色背景 - 您应该使用自定义适配器。覆盖bindView()函数,使背景变为最喜欢的背景,或者当它不是最喜欢的时候给它一个正常的背景。

我不知道您目前如何将数据库中的项目放入ListView,但继承SimpleCursorAdaptor可以很好地工作。

public class FavoritesItemAdapter extends SimpleCursorAdapter {

    public FavoritesItemAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
        super(context, layout, c, from, to, flags);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        super.bindView(view, context, cursor);

        // read the name from the database
        int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
        String name = cursor.getString(nameColumnIndex);

        // write the name to the TextView
        TextView nameText = (TextView) view.findViewById(R.id.item_name);
        nameText.setText(name);

        // set the background to normal or to red, depending on if it is the favorite one or not
        boolean isFavorite = db_verification(name);
        if (isFavorite) {
            nameText.setBackgroundResource(R.drawable.redcolor);
        } else {
            nameText.setBackgroundResource(android.R.color.transparent);
        }
    }

    public boolean db_verification(String name) {
        // this is a stub. You must use your own code here
        return name.equals("the favorite one");
    }
}

然后您可以扔掉ChangeMyFavoritesBG()并使用onCreate()中的适配器初始化ListView。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);

    Cursor cursor = readItemsFromDatabase();        
    String[] from = new String[] { "name_column" }; // mapping from database column name ...
    int[] to = new int[] { R.id.item_name };        // ... to View ID in the item's layout.
    FavoritesItemAdapter adapter = new FavoritesItemAdapter(this, R.layout.item_list, cursor, from, to, 0);

    ListView listview = (ListView) findViewById(R.id.listview);
    listview.setAdapter(adapter);
}
祝你好运!