android-更改ListVi上所选项目的背景颜色

我想知道如何更改listView上所选项目的背景颜色。 我只想更改用户单击的特定项目,这意味着如果用户单击另一个项目,它将被突出显示。 好吧,因为我希望它尽可能简单并使用默认的android listview,所以我改用以下代码:

record_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                try{
                    for (int ctr=0;ctr<=record_items.length;ctr++){
                        if(i==ctr){
                            record_list.getChildAt(ctr).setBackgroundColor(Color.CYAN);
                        }else{
                            record_list.getChildAt(ctr).setBackgroundColor(Color.WHITE);
                        }
                    }
                }
                catch (Exception e){
                    e.printStackTrace();
                }
                Log.v("Selected item",record_list.getItemAtPosition(i));
            }
        });

好的,这是可行的,但问题是它很慢。 现在我想知道是否还有其他方法可以实现与我相同的输出。

我尝试使用record_list.getSelectedView().setBackgroundColor(Color.CYAN);,但它给了我一个空指针异常。

我也尝试了选择器.xml,但也没有成功。此外,这里的ListView上有一个属性称为listSelector。 正如文档“可绘制用来表示列表中当前选定的项目”所言,这是一个可绘制。 我也相信这应该可以解决问题,是的,它可以在模拟器上解决问题,而不是在银河选项卡上解决问题。 我也尝试了其他方法,但没有任何效果。

KaHeL asked 2020-01-14T13:24:45Z
17个解决方案
72 votes

您可以跟踪当前选定元素的位置:

    OnItemClickListener listViewOnItemClick = new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
                mSelectedItem = position;
                mAdapter.notifyDataSetChanged();
        }
    };

并重写适配器的getView方法:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final View view = View.inflate(context, R.layout.item_list, null);

        if (position == mSelectedItem) {
            // set your color
        }

        return view;
    }

对我来说,它成功了。

Esteam answered 2020-01-14T13:25:03Z
68 votes

您可以使用选择器。 更改颜色值并根据需要修改以下内容。

可绘制文件夹中的bkg.xml

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

可绘制文件夹中的Pressed.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
<solid android:color="#FF1A47"/>  // color   
<stroke android:width="3dp"
        android:color="#0FECFF"/> // border
<padding android:left="5dp"
         android:top="5dp"
         android:right="5dp"
         android:bottom="5dp"/> 
<corners android:bottomRightRadius="7dp" // for rounded corners
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp"
         android:topRightRadius="7dp"/> 
</shape>

可绘制文件夹中的normal.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
<solid android:color="#FFFFFF"/>    
<stroke android:width="3dp"
        android:color="#0FECFF" />

<padding android:left="5dp"
         android:top="5dp"
         android:right="5dp"
         android:bottom="5dp"/> 
<corners android:bottomRightRadius="7dp"
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp"
         android:topRightRadius="7dp"/> 
</shape>

将背景可绘制对象设置为每行要放大的listview自定义布局

我建议将自定义列表视图与自定义适配器一起使用。

  android:background="@drawable/bkg"     

如果尚未使用自定义适配器,则可以将listselector设置为listview,如下所示

   android:listSelector="@drawable/bkg" 
Raghunandan answered 2020-01-14T13:25:49Z
23 votes

定义变量

private ListView mListView;

初始化变量

mListView = (ListView)findViewById(R.id.list_view);

ListView的OnItemClickListener

   mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adpterView, View view, int position,
                long id) {
            for (int i = 0; i < mListView.getChildCount(); i++) {
                if(position == i ){
                    mListView.getChildAt(i).setBackgroundColor(Color.BLUE);     
                }else{
                    mListView.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
                }
            }
        }
    });

生成并运行项目-完成

Hiren Patel answered 2020-01-14T13:26:22Z
15 votes

如果要在单击项目后使其保持突出显示状态,则需要手动将其设置为在onItemClick侦听器中被选中

Android ListView所选项目保持突出显示:

myList.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {   
        view.setSelected(true); // <== Will cause the highlight to remain
        //... do more stuff                          
    }});

假设您的选择器中有一个state_selected项:

<?xml version="1.0" encoding="utf-8"?>
  <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  <item android:state_enabled="true" android:state_pressed="true" android:drawable="@color/red" />
  <item android:state_enabled="true" android:state_focused="true" android:drawable="@color/red" />
  <item android:state_enabled="true" android:state_selected="true" android:drawable="@color/red" />
  <item android:drawable="@color/white" />
</selector>
ssawchenko answered 2020-01-14T13:26:50Z
7 votes

方法1:

在您的xml布局活动/片段中更新ListView:

<ListView
   ...
   android:choiceMode="singleChoice"
   android:listSelector="@android:color/darker_gray"
/>

就是这样,您完成了!

如果您想以编程方式处理此问题,请使用方法2 ...

方法2:

如果您使用的是ListFragment,则可以使用视图设置颜色来覆盖onListItemClick()。 保存当前选择的视图以重置上一个选择的颜色。

请注意,这仅适用于一个屏幕上的列表视图,因为视图已回收。

public class MyListFragment extends ListFragment {
    View previousSelectedItem;
...
    @Override
    public void onListItemClick(ListView parent, View v, int position, long id) {
        super.onListItemClick(parent, v, position, id);
        if (previousSelectedItem!=null) {
            previousSelectedItem.setBackgroundColor(Color.WHITE);
        }
        previousSelectedItem=v;
        v.setBackgroundColor(Color.BLUE);
    }
}
JMax answered 2020-01-14T13:27:37Z
6 votes

首先,您可以在可绘制文件夹drawable/list_item_selector.xml中创建如下所示的选择器xml文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_activated="true">
      <shape android:shape="rectangle">
        <solid android:color="#333333" />
        <padding android:left="5dp" android:right="5dp" />
      </shape></item>
    <item><shape android:shape="rectangle">
            <solid android:color="#222222" />
        </shape></item>

</selector>

然后在列表视图中将background指定为

android:background="@drawable/list_item_selector"
Nirali answered 2020-01-14T13:28:02Z
6 votes

对于那些想知道到底需要做什么来使行保持选中状态的人,即使您向下滚动也是如此。 它是state_activated其余部分由内部功能处理,您不必担心切换,可以选择多个项目。 我不需要使用notifyDataSetChanged()或setSelected(true)方法。

将此行添加到您的选择器文件中,对我而言drawable \ row_background.xml

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

    <item android:state_enabled="true" android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
    <item android:state_enabled="true" android:state_focused="true" android:drawable="@android:color/holo_blue_bright" />
    <item android:state_enabled="true" android:state_selected="true" android:drawable="@android:color/holo_blue_light" />
    <item android:state_activated="true" android:drawable="@android:color/holo_blue_light" />

    <item android:drawable="@android:color/transparent"/>
</selector>

然后在layout \ custom_row.xml中

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dip"
        android:background="@drawable/row_background"
        android:orientation="vertical">
  <TextView
        android:id="@+id/line1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

有关更多信息,我将其与ListView Adapter一起使用,使用         myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);         和         myList.setMultiChoiceModeListener(new MultiChoiceModeListener()...

来自此示例:[http://www.androidbegin.com/tutorial/android-delete-multiple-selected-items-listview-tutorial/]

另外,您(应该)将这种结构用于列表适配器的耦合:List myList = new ArrayList();

而不是:ArrayList myList = new ArrayList();

说明:Java中的类型列表与类型ArrayList

Emil answered 2020-01-14T13:28:53Z
3 votes

我找到的最简单的方法:

在您的活动XML中添加以下行:

<ListView 
... 
android:choiceMode="singleChoice"
android:listSelector="#666666"
/>

或以编程方式设置以下属性:

listView.setSelector(Drawable selector)
listView.setSelector(int resourceId)

我的特定示例:

   <ListView
            android:choiceMode="singleChoice"
            android:listSelector="#666666"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/listView"/>

感谢AJG:[https://stackoverflow.com/a/25131125/1687010]

Taochok answered 2020-01-14T13:29:31Z
2 votes

使用下面的xml作为listitem背景,它将解决所有问题。尽管您向下滚动,所选内容仍将突出显示。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/holo_orange_dark" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_green_light" android:state_selected="true"/>
<item android:drawable="@android:color/holo_green_light" android:state_activated="true"/>

谢谢,那根德拉

Anisetti Nagendra answered 2020-01-14T13:29:55Z
2 votes

我也在做类似的事情:突出显示所选列表项目的背景(将其更改为红色),并将项目内的文本颜色设置为白色。

我可以想出一种“简单但不高效”的方式:保持选定项在自定义适配器中的位置,然后在ListView的activatedBackgroundIndicator实现中进行更改:

// The OnItemClickListener implementation
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    mListViewAdapter.setSelectedItem(position);
}

// The custom Adapter
private int mSelectedPosition = -1;
public void setSelectedItem (int itemPosition) {
    mSelectedPosition = itemPosition;
    notifyDataSetChanged();
}

然后使用activatedBackgroundIndicator方法更新所选项目的背景和文本颜色。

// The custom Adapter
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ...
    if (position == mSelectedPosition) {
        // customize the selected item's background and sub views
        convertView.setBackgroundColor(YOUR_HIGHLIGHT_COLOR);
        textView.setTextColor(TEXT_COLOR);
    } else {
        ...
    }
}

经过一会儿的搜索,我发现很多人提到要设置activatedBackgroundIndicator。经过一段时间的尝试,我发现突出显示所选ListView项目背景的最简单方法是,只需将两行设置为ListView的布局资源即可:

android:choiceMode="singleChoice"
android:listSelector="YOUR_COLOR"

还有其他使其工作的方法,例如自定义activatedBackgroundIndicator主题。 但是我认为这将是一个更为通用的解决方案,因为它将影响整个主题。

Ethan Zhong answered 2020-01-14T13:30:34Z
2 votes

我知道这是一个老问题,但是我为此需求提供了一个简单的解决方案(无循环!):

//On your adapter create a variable:
private View lastSelectedItem;

//Define the folowing method:
private void toggleBackgroundItem(View view) {
    if (lastSelectedItem != null) {
        lastSelectedItem.setBackgroundColor(Color.TRANSPARENT);
    }
    view.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
    lastSelectedItem = view;

}
//finally invoque the method onItemClick
lvSac.setOnItemClickListener(new AdapterView.OnItemClickListener()

{
    @Override
    public void onItemClick (AdapterView < ? > adapterView, View view,int i, long l){

    toggleBackgroundItem(view);
}
}
Eumagnun answered 2020-01-14T13:30:54Z
1 votes

假设您希望每次单击一个项目。 然后这段代码就可以正常工作了。 让我们以listview名称作为stlist

stList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        // here i overide the onitemclick method in onitemclick listener
            public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            //color change
            //selected item colored

            for(int i=0; i<stList.getAdapter().getCount();i++)
            {
                stList.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
            }

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

    });
Miraj Hamid answered 2020-01-14T13:31:14Z
1 votes

这是一个即使列表很长也可以处理选择的简单方法:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.list_item, null);
    //Handle your items.
    //StringHolder.mSelectedItem is a public static variable.
    if(getItemId(position)==StringHolder.mSelectedItem){
        rowView.setBackgroundColor(Color.LTGRAY);

    }else{
        rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    return rowView;
}

然后在您的onclicklistener中:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
            catagoryAdapter.notifyDataSetChanged();
.....
Wasiun A. Khan answered 2020-01-14T13:31:38Z
1 votes
View updateview;// above oncreate method
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);


listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         if (updateview != null) 
            updateview.setBackgroundColor(Color.TRANSPARENT);
         updateview = view;   

         view.setBackgroundColor(Color.CYAN);
     }
});
nandish answered 2020-01-14T13:31:54Z
0 votes

在ListView集合中:

android:choiceMode="singleChoice"

为背景创建选择器(drawable / selector_gray.xml):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/gray" android:state_checked="true" />
    <item android:drawable="@color/white" />
</selector>

为列表添加项目:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:padding="5dp"
    android:background="@drawable/selector_gray"
    android:textColor="@color/colorPrimary"
    tools:text="Your text" />

在ViewHolder中,您可以为此项充气。

CoolMind answered 2020-01-14T13:32:26Z
0 votes

非常简单 在“ OnItemClick”的构造函数中,使用参数“ view”,它是第二个代表listView或GridView的项目视图的参数,它成为由adapterView自身创建的新项目的视图。 因此,仅将新颜色设置为“ SELECTED ITEM”本身,请执行以下操作:

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l){ //view is instead of the view like textView , ImageView, or whatever view.setBackgroundColor(Color.green); }

如果您执行任何其他代码来设置新颜色,您将面临尴尬的行为,例如绿色将应用于未单击的项目。

Mhd Rami Al Hilwany Al Refai answered 2020-01-14T13:32:56Z
0 votes

nameofList.getChildAt(position).setBackgroundColor(RED);

为我工作

Vee Lad answered 2020-01-14T13:33:20Z
translate from https://stackoverflow.com:/questions/16976431/change-background-color-of-selected-item-on-a-listview