更改 ListView 上所选项目的背景颜色
Posted
技术标签:
【中文标题】更改 ListView 上所选项目的背景颜色【英文标题】:Change background color of selected item on a ListView 【发布时间】:2013-06-03 07:23:26 【问题描述】:我想知道如何更改我的 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);
,但它给了我一个空指针异常。
我也尝试了 selector.xml,但它也没有成功。 此外,ListView 上还有一个属性,称为 listSelector。正如文档“Drawable used to指示列表中当前选定的项目”所述,它是一个drawable。我也相信这应该可以解决问题,是的,它可以在我的模拟器上解决问题,但不是在我的银河选项卡上。我也尝试了其他方法,但没有达到我想要的效果。
【问题讨论】:
使用 xml 文件作为列表视图。 这个选项你勾选了吗,list.setSelector(R.drawable.detail_hover);我的 deutil_hover 是 .png 可绘制对象。试试这个,希望对你有帮助。 你在onitem点击中得到视图对象,所以改变那个视图的背景颜色并在下次点击时将它保存为prvsselected视图检查prvsselect视图是否为空,如果它不为空则改变它的颜色默认一个 对于大于 1 个屏幕高度的列表,此方法将失败。 2行有效解决方案:***.com/questions/16976431/… 【参考方案1】:您可以跟踪当前选定元素的位置:
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;
对我来说,它成功了。
【讨论】:
你应该只需要在 onItemClick 监听器中设置 view.setSelected(true):***.com/questions/16189651/… Esteam 的解决方案是正确的。仅使用 view.setSelected(true) 的问题是这些视图被回收。一旦您有一个足够大的列表可以滚动,这将不再有效。 对我来说,我不得不使用id
而不是position
,因为position
从 1 开始,而我的适配器中的项目从 0 开始。虽然我可能很少遇到这种情况,但是我想我会提到它以防有人被卡住。
@HuskyHuskie 不是因为你有一个标题视图吗?我总是使用position
并提取标题视图计数。
这将在 Lollypop 中分解 - 如果您在项目上设置背景,您将不再看到那些花哨的点击动画。【参考方案2】:
您可以使用选择器。更改颜色值并根据需要修改以下内容。
可绘制文件夹中的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>
drawable 文件夹中的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:
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>
drawable 文件夹中的 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:
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>
将背景drawable设置为listview自定义布局,为每一行充气
我建议使用带有自定义适配器的自定义列表视图。
android:background="@drawable/bkg"
如果您没有使用自定义适配器,您可以将 listselector 设置为 listview,如下所示
android:listSelector="@drawable/bkg"
【讨论】:
我试过这段代码,但是当我点击列表项时,它的颜色只会改变几秒钟,如果我想将项目显示为选中。 @rb16 这就是选择器的用途。如果不是,您正在寻找不同的解决方案,而不是这个 目前,当我点击一个列表项时,它的颜色会改变,而它在释放它的颜色更改为默认颜色后按下它。但我的要求是我想将点击的项目显示为选中,直到我不点击在其他列表项上 为了选择项目,将state_selected="true"
的条目添加到选择器xml。
仅仅改变背景颜色需要另外 3 个 xml 文件。天哪……【参考方案3】:
定义变量
private ListView mListView;
初始化变量
mListView = (ListView)findViewById(R.id.list_view);
列表视图的 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);
);
构建并运行项目 - 完成
【讨论】:
嗨,您的答案与我尝试实施的答案几乎相同,但没有按我想要的方式工作。近两年前,这个问题也得到了回答和接受。 :) @KaHeL,感谢分享关注,我已经尝试了上述和其他解决方案,但我无法获得正确的结果,所以我用自己的解决方案尝试了它,幸运的是它对我有用。谢谢 这个有效!该解决方案对我有用,而其他解决方案则没有。我在“selectItem(position);”行之后将这个“for”语句添加到我的导航抽屉中。现在它就像一个魅力。点赞!我需要解释为什么这个工作:otherS 留下了选中的选项,所以,在选择另一个之后,有两个选项被选中,这个解决方案改变了所有选项的颜色,只有一个保持所需的颜色。 @JoseManuelAbarcaRodríguez,很高兴为您提供帮助并感谢您的赞赏。 :) 小心,如果列表超过一个屏幕高度,它会被空指针压碎。另外,如果你有一个包含数千个项目的列表,当你只看到几个时它会一个接一个。【参考方案4】:如果您希望在单击后使项目保持突出显示,则需要手动将其设置为在 onItemClick 侦听器中被选中
Android ListView selected item stay highlighted:
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>
【讨论】:
view.setSelected(true);
使我的项目始终被选中。如何让它不被选中?
@Sonhja 您应该每次默认取消选中每个项目并检查 getView 如果等于所选位置然后选择 true 否则为 false【参考方案5】:
方法一:
在您的 xml 布局活动/片段中更新 ListView:
<ListView
...
android:choiceMode="singleChoice"
android:listSelector="@android:color/darker_gray"
/>
就是这样,你完成了!
如果您想以编程方式处理此问题,请使用方法 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);
【讨论】:
【参考方案6】:对于那些想知道究竟需要做什么来保持选中行的人,即使您向上向下滚动也是如此。就是 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_
android:layout_
android:padding="10dip"
android:background="@drawable/row_background"
android:orientation="vertical">
<TextView
android:id="@+id/line1"
android:layout_
android:layout_ />
</LinearLayout>
有关更多信息,我将它与 ListView 适配器一起使用,使用 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();
解释:Type List vs type ArrayList in Java
【讨论】:
感谢您的回答。 嗨,Emil,您的解决方案是否可以通过编程方式取消选择该项目? 嗨@Sam,我的解决方案基于我链接的示例。这是一个非常好的 ListView 教程,在此之后,您将大致了解 Lists 的工作原理以及代码如何与 XML 文件交互。你必须知道那里提供的所有信息,跳过这个太基础了,那个教程是直截了当的。我浏览了其他几个,但他们的介绍太混乱或误导了,所以中途放弃了。一旦“自动”工作,试试这个程序化方法:***.com/questions/10788688/…【参考方案7】:首先,您可以在您的可绘制文件夹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>
然后在您的列表视图中指定背景为
android:background="@drawable/list_item_selector"
【讨论】:
这个很有趣。我会试试这个,稍后再给你反馈。 :) 嗨,使用这种方法,是否可以通过编程方式取消选择该项目?谢谢...【参考方案8】:我发现的最简单的方法:
在您的活动 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_
android:layout_
android:id="@+id/listView"/>
感谢 AJG: https://***.com/a/25131125/1687010
【讨论】:
【参考方案9】:我也在做类似的事情:突出显示所选列表项的背景(将其更改为红色)并将项目中的文本颜色设置为白色。
我可以想出一个“简单但效率不高”的方法:
在自定义适配器中维护选定项的位置,并在 ListView 的OnItemClickListener
实现中更改它:
// 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();
然后在getView()
方法中更新选中项的背景和文字颜色。
// 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
...
搜索了一会,发现很多人提到要设置android:listSelector="YOUR_SELECTOR"
。经过一段时间的尝试,我发现最简单的方法是突出显示选定的 ListView 项目的背景,只需将两行设置为 ListView 的布局资源:
android:choiceMode="singleChoice"
android:listSelector="YOUR_COLOR"
还有其他方法可以使它工作,例如自定义activatedBackgroundIndicator
主题。但我认为这将是一个更通用的解决方案,因为它会影响整个主题。
【讨论】:
【参考方案10】: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);
);
【讨论】:
这是我能找到的最简单的方法。只要您选择列表中的另一个元素,只有一个项目将保持突出显示。上一个将被自动取消选择 与已经接受的答案相比,您的答案提供了什么?【参考方案11】:使用下面的 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"/>
谢谢, 纳根德拉
【讨论】:
嗨,Nagendra,您的解决方案是否可以通过编程方式取消选择该项目?【参考方案12】:我知道这是一个老问题,但我为这个需求提供了一个简单的解决方案(没有循环!):
//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);
【讨论】:
【参考方案13】:在 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_
android:layout_
android:gravity="center"
android:padding="5dp"
android:background="@drawable/selector_gray"
android:textColor="@color/colorPrimary"
tools:text="Your text" />
您可以在 ViewHolder 中为该项目充气。
【讨论】:
我将“android:state_checked”更改为“android:state_selected”,当我在列表视图的 onItemClickedListener 中调用 view.setSelected(true) 时,它可以工作。 @civic.LiLister,谢谢,这是一个好点。我认为,它可以取决于列表项。但请同意,您的变体更有帮助,也更常用。【参考方案14】:假设您希望每次点击一个项目。然后这段代码运行良好。让我们将列表视图名称作为 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);
);
【讨论】:
小心,如果列表超过一个屏幕高度,它会被空指针压碎。另外,如果你有一个包含数千个项目的列表,当你只看到几个时它会一个接一个。【参考方案15】:这是一个简单的方法,即使列表也很长,也可以处理选择:
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();
.....
【讨论】:
什么是StringHolder
?【参考方案16】:
nameofList.getChildAt(position).setBackgroundColor(RED);
为我工作
【讨论】:
【参考方案17】:这很简单。在“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);
如果您执行任何不同的代码来设置新颜色,您将面临尴尬的行为,例如绿色将应用于未点击的项目。
【讨论】:
以上是关于更改 ListView 上所选项目的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Forms:如何更改 flowlistview 中所选项目的背景颜色?