在安卓上更改ListView项目的背景颜色

73

我该如何在每个ListView项上单独更改背景颜色?当我在ListView项布局中使用android:backgroundColor时,可以实现这一点,但是列表选择器不再可见。我可以通过将drawSelectorOnTop设置为true来使选择器再次可见,但是选择器会覆盖整个项目。

有什么办法可以更改这些背景颜色并保留选择器吗?

PS 我不想改变选择器本身。

编辑:Gmail应用程序的作者已经成功实现了这一点,所以肯定是可以实现的。


我已经在这里回答了... https://dev59.com/v3fZa4cB1Zd3GeqPNBIq#56853441 - Goddard
18个回答

37

如果您想使用不同的颜色,您需要为每种颜色创建一个不同状态的可绘制对象。

例如: list_selector_read.xmllist_selector_unread.xml

您只需将所有内容设置为透明,除了android:state_window_focused="false"项目。

然后,在绘制列表时,对于每一行,您调用setBackgroundResource(R.drawable.list_selector_unread/read)

在ListView上根本不设置 listSelector,这将保留您特定 Android 版本的默认选择器。


7
这应该是被采纳的答案。而row.setBackgroundResource()方法要么在YourCustomArrayAdapter.getView()方法中调用,或者你可以通过在res/layout/your_list_entry_layout.xml文件中设置最外层元素的属性为android:background="@drawable/your_list_entry_selector"来完全避免使用这个方法。 - Engineer
@Nick Wiggill 感谢您的评论。帮了很大的忙。 - Rohit Walavalkar
1
不介意提供一下放入list_selector_read.xml的代码示例。 - Zapnologica
@Zapnologica 这是一个标准的颜色状态列表资源。您可以随时在线查看Android源代码库并查看其样式资源以获取见解。 - MandisaW
更正:这里需要一个状态列表可绘制资源,而不是颜色状态列表。 - MandisaW

28

这是基于上述代码的修改,一个最简单的代码:

private static int save = -1;

public void onListItemClick(ListView parent, View v, int position, long id) { 

    parent.getChildAt(position).setBackgroundColor(Color.BLUE);

    if (save != -1 && save != position){
        parent.getChildAt(save).setBackgroundColor(Color.BLACK);
    }

    save = position;                

}

希望你觉得它有用

问候!


1
代码运行良好。但是使用此代码后,list_selector效果消失了。也就是说,在使用此代码后,当我点击list_item时,它不会产生点击效果。 - Sathish Kumar J
很棒的解决方案! - sonichy

23

好的,我通过以下方式使其工作:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" android:drawable="@color/BackgroundColor" />
    <item android:drawable="@color/transparent" />
</selector>

个人见解,因人而异!


11

似乎没有人提供仅使用适配器来完成此操作的示例,因此我想发布我的代码片段,用于显示ListView,其中“curSelected”项具有不同的背景:

final ListView lv = (ListView)findViewById(R.id.lv);
lv.setAdapter(new BaseAdapter()
{
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            convertView = new TextView(ListHighlightTestActivity.this);
            convertView.setPadding(10, 10, 10, 10);
            ((TextView)convertView).setTextColor(Color.WHITE);
        }

        convertView.setBackgroundColor((position == curSelected) ? 
            Color.argb(0x80, 0x20, 0xa0, 0x40) : Color.argb(0, 0, 0, 0));
        ((TextView)convertView).setText((String)getItem(position));

        return convertView;
    }

    public long getItemId(int position)
    {
        return position;
    }

    public Object getItem(int position)
    {
        return "item " + position;
    }

    public int getCount()
    {
        return 20;
    }
});

对我来说,当列表项的外观需要动态变化时,这总是一种有用的方法。


9
mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);

for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }

 }

1
它同时突出显示了2个项目。其中存在一些问题。 - Rohit
即使我的手指离开屏幕,背景仍然是蓝色。 - suitianshi

8

来自Android 2.2邮件应用的源代码:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false" android:state_selected="true"
        android:drawable="@android:color/transparent" />
    <item android:state_selected="true"
        android:drawable="@android:color/transparent" />
    <item android:state_pressed="true" android:state_selected="false"
        android:drawable="@android:color/transparent" />
    <item android:state_selected="false"
        android:drawable="@color/message_item_read" />
</selector>

没有更多可说的了...


7
最简单的方法是这样的。在您的ListArrayAdapter内部,只需执行以下操作
if(your condition here) rowView.setBackgroundColor(Color.parseColor("#20FFFFFF"));

不要过于复杂化


3
这个回答并没有回答提出的问题,他想要保持列表选择器,但是希望其中某些行有不同的背景颜色。你的回答将会移除列表选择器的样式! - Mohammad Zekrallah
1
@MohammadZekrallah 我想我是一个不听话的孩子,不能收到圣诞礼物了。 - OWADVL
虽然它没有回答具体的问题,但在我的应用程序中起到了作用。谢谢。 - Victor Lee

6

您是希望在单击自定义列表项时更改其背景颜色吗?

如果是这样的话:

您只需将以下代码添加到xml中的listview布局中。


android:drawSelectorOnTop="true" android:listSelector="@android:drawable/list_selector_background"


此处的列表选择器使用默认选择器,其颜色为深灰色。您可以制作自己的可绘制对象,并将其分配给上述列表选择器。

希望这就是您想要的。


5

这是一个简单的代码,可以更改项目布局中的所有内容(自定义列表视图扩展了BaseAdapter):

lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {

            RelativeLayout layout=(RelativeLayout) arg1.findViewById(R.id.rel_cell_left);
            layout.setBackgroundColor(Color.YELLOW);



        }
    });

2

以下是跑步时速慢的原因

mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);

for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }

 }

被以下内容所取代

int pos = 0;
int save = -1;
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
            //Always set the item clicked blue background
            view.setBackgroundColor(Color.BLUE);

            if (pos == 0) {
                if (save != -1) {
                    parent.getChildAt(save).setBackgroundColor(Color.BLACK);
                }
                save = position;
                pos++;
                Log.d("Pos = 0", "Running");

            } else {
                parent.getChildAt(save).setBackgroundColor(Color.BLACK);
                save = position;
                pos = 0;
                Log.d("Pos # 0", "Running");
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接