Listview - 更改项目的背景颜色

时间:2014-06-26 14:39:30

标签: java android listview

我试图让用户已经在列表视图中点击的行的背景颜色发生了变化,为了做到这一点,我使用保存在SharedPreferences中的arraylist来控制点击的行的ID,问题是颜色几乎随机变化。

代码:

    private static class ItemHolder {
        public TextView TXTTitle, TXTArtist, TXTid, TXTLikes;
        public RelativeLayout back;
    }

    @Override
    public View getView(final int position, View view, ViewGroup root) {
        ItemHolder holder = new ItemHolder();

        if (view == null) {
            view = inflater.inflate(R.layout.list_item, root, false);

            RelativeLayout _back = (RelativeLayout) view.findViewById(R.id.bg_item);

            holder.back = _back;

            // paint oldies
            Set<String> _set = new HashSet<String>();
            _set = Prefs.getStringSet("arrOfOldies", _set);
            for(int i = 0; i <= _set.size()  ; i++){
                if(_set.contains(IDs.get(position))){
                //oldie
                            holder.back.setBackgroundColor(Color.parseColor("#D0D0D0"));
                    }
            }

            view.setTag(holder);
        } else {
                holder = (ItemHolder) view.getTag();       
        }
    }

我认为它与listview的构建方式,问题是什么以及如何修复它有关?

3 个答案:

答案 0 :(得分:1)

我想补充曼尼托巴省的答案,如果从未选择该项目,您还必须重置背景。 了解使用convertView和项目持有者的重点是重用视图进行优化。如果您重复使用已为某个项目选择过的项目中的视图,那么背景颜色仍将在此处。

尝试:

@Override
public View getView(final int position, View view, ViewGroup root)
{
    ItemHolder holder = null;

    if (view == null)
    {
        view = inflater.inflate(R.layout.list_item, root, false);
        holder = new ItemHolder();

        holder.back = (RelativeLayout) view.findViewById(R.id.bg_item);
        view.setTag(holder);
    }
    else
    {
        holder = (ItemHolder) view.getTag();
    }

    // paint oldies
    Set<String> _set = new HashSet<String>();
    _set = Prefs.getStringSet("arrOfOldies", _set);
    for(int i = 0; i <= _set.size()  ; i++)
    {
        if(_set.contains(IDs.get(position)))
        {
            holder.back.setBackgroundColor(Color.parseColor("#D0D0D0"));
        }
        else 
        {
            //add this else clause.
            holder.back.setBackgroundColor( YOUR_DEFAULT_BACKGROUND_COLOR ); 
        }
    }
}

答案 1 :(得分:0)

您犯了一个小错误,在检索现有的持有人后移动background部分。 这是要使用的干净代码。

private static class ItemHolder
{
    public TextView TXTTitle, TXTArtist, TXTid, TXTLikes;
    public RelativeLayout back;

    @Override
    public View getView(final int position, View view, ViewGroup root)
    {
        ItemHolder holder = null;

        if (view == null)
        {
            view = inflater.inflate(R.layout.list_item, root, false);
            holder = new ItemHolder();

            holder.back = (RelativeLayout) view.findViewById(R.id.bg_item);
            view.setTag(holder);
        }
        else
        {
            holder = (ItemHolder) view.getTag();
        }

        // paint oldies
        Set<String> _set = new HashSet<String>();
        _set = Prefs.getStringSet("arrOfOldies", _set);
        if(_set.contains(IDs.get(position)))
        {
            //oldie
            holder.back.setBackgroundColor(Color.parseColor("#D0D0D0"));
        }else{
            holder.back.setBackgroundColor(Color.parseColor("#ffffff"));
        }
    }
}

答案 2 :(得分:0)

你的逻辑错了。您没有在代码中考虑回收ListViews。此外,您无需检查_set是否包含您的项目,因为您的设置中有多个对象。您应该重构代码以反映这些要点:

  • 您最大的问题是,除非您的视图为空,否则您永远不会为您设置 holper 变量,并且它只是空的次数,因为同时有适合您屏幕的列表项 - 当它们被回收时,你的颜色会变得怪异。解决这个问题,它将得到解决。这是一些ListView recycling info
  • 将您的_set移出getView函数
  • 摆脱for循环迭代_set
  • 的值