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

Posted

技术标签:

【中文标题】在 Android 上更改 ListView 项目的背景颜色【英文标题】:Changing background color of ListView items on Android 【发布时间】:2011-01-14 03:15:48 【问题描述】:

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

任何想法如何更改这些背景颜色并保留选择器?

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

编辑:GMail 应用程序的作者已经成功实现了这一点,所以这绝对是可能的。

【问题讨论】:

我已经在这里回答了...***.com/questions/18917214/… 【参考方案1】:

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

例如:list_selector_read.xmllist_selector_unread.xml

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

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

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

【讨论】:

+1 这应该是公认的答案。而row.setBackgroundResource() 发生在YourCustomArrayAdapter.getView() 中,或者您可以通过在res/layout/your_list_entry_layout.xml 的最外层元素上简单地设置android:background="@drawable/your_list_entry_selector" 来完全放弃这一点。 @Nick Wiggill 感谢您的评论。帮助很大 不介意进入 list_selector_read.xml 的代码示例 @Zapnologica 这是标准的Color State List resource。您可以随时在线查看 Android 源代码库并查看他们的样式资源以获取见解。 更正:这里需要State List Drawable resource,而不是颜色状态列表。【参考方案2】:

这是在上面代码的基础上修改的,最简单的代码:

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;                


希望对你有用

你好!

【讨论】:

效果很好。但使用此代码后 list_seletor 效果消失了。 IE。使用此代码后,当我点击 list_item 时,它没有点击效果 很好的解决方案!【参考方案3】:

好的,我让它像这样工作:

<?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!

【讨论】:

【参考方案4】:

似乎没有人提供任何单独使用适配器执行此操作的示例,所以我想我会发布我的代码 sn-p 用于显示“curSelected”项目具有不同背景的 ListViews:

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;
    
);

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

【讨论】:

【参考方案5】:
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);
     

 

【讨论】:

它同时突出显示 2 个项目。里面有问题。 即使我的手指离开屏幕,背景仍然是蓝色【参考方案6】:

来自Android的2.2Email App的源码:

<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"));

不要太复杂

【讨论】:

这不是在回答所提出的问题.. 他想为某些行维护具有不同背景颜色的列表选择器.. 您的回答将删除列表选择器样式! @MohammadZekrallah 我想我是个淘气的男孩,圣诞节不会收到任何礼物 虽然它没有回答具体问题,但在我的应用程序中起到了作用。谢谢。【参考方案8】:

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

如果是这样:

您只需将以下代码添加到 xml 中的列表视图布局中。


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


这里的列表选择器使用默认选择器,它具有深灰色。 您可以制作自己的可绘制对象并将其分配给上述列表选择器。

希望这是你想要的。

【讨论】:

【参考方案9】:

更改所有项目布局的简单代码(自定义列表视图扩展 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);



        
    );

【讨论】:

【参考方案10】:

在运行中非常缓慢地跟随方式

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");
            

【讨论】:

【参考方案11】:

通过更改 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;

【讨论】:

【参考方案12】:

看看List14 example。在getView() 中,您可以为每个条目调用convertView.setBackgroundDrawable()。例如,您可以有一个类成员计数器来决定使用哪个背景调用它以获得交替背景。

【讨论】:

不幸的是,这不起作用。设置 BackgroundDrawable 与设置 BackgroundColor 的效果相同 - 先绘制选择器,所以它被隐藏了。 将您的 android:drawSelectorOnTop 更改为 false【参考方案13】:

在列表视图中,您可以添加 android:listselector=你想要的颜色名称。

这在我的应用中运行良好。

【讨论】:

【参考方案14】:

这方面的最佳教程可以在here 找到。

关键部分:

    一定要在onItemClick中调用view.setSelected(true),否则看不到选中项背景 保留选择器中的状态顺序,否则您会看到背景颜色出现不可预知的行为(state_selected 后跟 state_pressed

【讨论】:

【参考方案15】:

你可以这样做。

 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);

【讨论】:

【参考方案16】:

如果为onItemClick事件添加setBackgroundColor,除非你能把它放在点击事件之后,否则它不会起作用。

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

也许你可以添加一些控制标志来确定个别行的背景颜色,然后根据这个控制标志修改getView方法来设置颜色。因此,当它重绘屏幕时,背景颜色会发生变化。

我也在寻找官方的解决方案。

【讨论】:

【参考方案17】:

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

<ListView
                android:id="@+id/list"
                android:layout_
                android:layout_
                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_
            android:layout_>

    <RelativeLayout 
        android:layout_
        android:layout_
        android:padding="8dp"
        android:paddingLeft="16dp"
        android:paddingStart="16dp"
        android:paddingRight="16dp"
        android:paddingEnd="16dp">

            <ImageView
                android:id="@+id/imgViewIcon"
                android:layout_
                android:layout_
                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_
                android:layout_
                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_
                android:layout_
                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

【讨论】:

【参考方案18】:

这就是我使用的(Kotlin):

if(blablabla == "whatever") 
    view.setBackgroundColor(getColor(context, R.color.teal_200))
 else 
    view.setBackgroundColor(getColor(context, R.color.teal_700))

【讨论】:

以上是关于在 Android 上更改 ListView 项目的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

Android中的ListView直到我触摸才显示项目

Android如何在每个listview列表项上添加图标并更改文本颜色、背景颜色

如何根据 android studio 中的 listview 项目点击更改活动图像和文本? java 或 kotlin

Android:使用 parsequery 适配器在 listview 中更改 imageview 的图像

单击时可扩展的listview android更改布局

更改 ListView 项目背景颜色但保留默认选择器样式?