在Android上更改ListView项的背景颜色


72

如何按ListView项目更改项目的背景颜色。当我android:backgroundColorListView项目布局中使用时,可以实现此目的,但是列表选择器不再可见。我可以通过将设置drawSelectorOnTop为true来使选择器再次可见,但是选择器会覆盖整个项目。

有什么想法如何更改这些背景颜色并保留选择器吗?

PS我宁愿不更改选择器本身。

编辑:GMail应用程序的作者已经设法实现了这一目标,因此这绝对是可能的。


我在这里回答了这个问题… stackoverflow.com
Goddard

Answers:


37

您必须为要使用的每种颜色创建一个不同的可绘制状态。

例如:list_selector_read.xmllist_selector_unread.xml

您需要做的就是将除android:state_window_focused="false"项目外的所有内容都设置为透明。

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

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


6
+1这应该是公认的答案。并且row.setBackgroundResource()发生在YourCustomArrayAdapter.getView()OR中,否则,您只需设置android:background="@drawable/your_list_entry_selector"的最外层元素就可以完全放弃这一点 res/layout/your_list_entry_layout.xml
工程师

@Nick Wiggill感谢您的评论。帮助了很多
Rohit Walavalkar 2013年

1
不会介意进入list_selector_read.xml的代码示例
Zapnologica 2014年

@Zapnologica这是标准的颜色状态列表资源。您随时可以在线查看Android源代码回购,并查看其样式资源以了解情况。
MandisaW

更正:这里需要状态列表可绘制资源,而不是颜色状态列表。
MandisaW

27

这是基于以上代码(最简单的代码)的修改:

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_seletor效果消失了。即。使用此代码后,当我单击list_item时,它没有产生点击效果
Sathish Kumar J

伟大的解决方案!
sonichy '17

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>

YMMV!


11

似乎没有人提供仅使用适配器来执行此操作的任何示例,因此我想我会发布我的代码段以显示ListViews,其中“ 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;
    }
});

当列表项的外观需要动态更改时,这一直是对我有用的方法。


8
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
它同时突出显示两个项目。有一些问题。
罗希特(Rohit)2012年

背景仍是蓝色,即使我的手指离开屏幕
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's

1
@MohammadZekrallah我想我是一个调皮的男孩,不会收到任何圣诞节礼物
OWADVL '16

尽管它无法回答特定问题,但在我的应用中达到了目的。谢谢。
维克多·李

5

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

如果是这样的话:

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


android:drawSelectorOnTop =“ true” android:listSelector =“ @ android:drawable / list_selector_background”


此处的列表选择器使用具有深灰色的默认选择器。您可以制作自己的drawable并将其分配给如上所述的列表选择器。

希望这就是您想要的。


5

简单的代码即可更改项目布局(自定义listview扩展了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");
            }

2

通过更改Francisco Cabezas的代码,我得到了以下信息:

private int selectedRow = -1;

...

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    parent.getChildAt(position).setBackgroundResource(R.color.orange);
    if (selectedRow != -1 && selectedRow != position) {
        parent.getChildAt(selectedRow).setBackgroundResource(R.color.black);
    }
    selectedRow = position;

1

看一下List14示例。在getView()您可以调用convertView.setBackgroundDrawable()每个条目。例如,您可以让一个类成员计数器决定调用哪个背景来获得交替的背景。


不幸的是,这不起作用。设置BackgroundDrawable与设置BackgroundColor具有相同的效果-首先绘制选择器,使其隐藏。
MarekStój'10

2
更改android:drawSelectorOnTopfalse
CommonsWare 2010年


1

最好的教程可以在这里找到。

关键部分:

  1. 当然调用view.setSelected(true)onItemClick,否则您无法看到所选择的项目背景
  2. 在选择器中保留状态顺序,否则您将在背景色中看到不可预测的行为(state_selected随后是state_pressed

1

你可以这样做。

 final List<String> fruits_list = new ArrayList<String>(Arrays.asList(fruits));

    // Create an ArrayAdapter from List
    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
            (this, android.R.layout.simple_list_item_1, fruits_list){
        @Override
        public View getView(int position, View convertView, ViewGroup parent){
            // Get the current item from ListView
            View view = super.getView(position,convertView,parent);
            if(position %2 == 1)
            {
                // Set a background color for ListView regular row/item
                view.setBackgroundColor(Color.parseColor("#FFB6B546"));
            }
            else
            {
                // Set the background color for alternate row/item
                view.setBackgroundColor(Color.parseColor("#FFCCCB4C"));
            }
            return view;
        }
    };

    // DataBind ListView with items from ArrayAdapter
    lv.setAdapter(arrayAdapter);
}

}


0

如果setBackgroundColor为onItemClick事件添加了,则除非将其放在click事件之后,否则它将不起作用。

尝试在适配器的getView方法中添加调试代码,您将发现只要单击屏幕,就会再次调用getView。因此,设置背景色后,系统将使用原始设置重新绘制屏幕。不知道为什么每次单击都会浪费重建屏幕的资源,已经有其他方法可以通知系统在需要时重新绘制屏幕。

也许您可以添加一些控制标志来确定单个行的背景颜色,然后修改getView方法以根据该控制标志来设置颜色。因此,当重新绘制屏幕时,背景色将被更改。

我也在寻找一个正式的解决方案。


0

我尝试了上面的所有答案..没有一个对我有用..最终成功了,并在我的应用程序中使用了..它将提供已读/未读列表项颜色,同时保持两种状态的listselector样式:

<ListView
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:listSelector="@drawable/selectable_item_background_general"
                android:drawSelectorOnTop="true"
                android:fadingEdge="none"
                android:scrollbarStyle="outsideOverlay"
                android:choiceMode="singleChoice" />

selectable_item_background_general.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
    <item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/bg_item_selected_drawable" />
    <item android:state_pressed="true" android:drawable="@drawable/bg_item_selected_drawable" />
    <item android:drawable="@android:color/transparent" />
</selector>

bg_item_selected_drawable.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#12000000" />
</shape>

notification_list_itemlayout.xml:

<RelativeLayout 
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/rowItemContainer"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:paddingLeft="16dp"
        android:paddingStart="16dp"
        android:paddingRight="16dp"
        android:paddingEnd="16dp">

            <ImageView
                android:id="@+id/imgViewIcon"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:src="@drawable/cura_logo_symbol_small"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_marginRight="8dp"
                android:layout_marginEnd="8dp" />
            <TextView
                android:id="@+id/tvNotificationText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/imgViewIcon"
                android:layout_toRightOf="@+id/imgViewIcon"
                android:layout_toEndOf="@+id/imgViewIcon"
                android:textSize="@dimen/subtitle"
                android:textStyle="normal" />
            <TextView
                android:id="@+id/tvNotificationTime"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="1dip"
                android:layout_below="@+id/tvNotificationText"
                android:layout_toRightOf="@+id/imgViewIcon"
                android:layout_toEndOf="@+id/imgViewIcon"
                android:textSize="@dimen/subtitle" />
        </RelativeLayout>
</RelativeLayout>

最后,在您的适配器中:

if (!Model.Read)
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.ParseColor ("#FFFDD0")); // unread color
else
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.White); // read color
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.