Android - 单击后保持 ListView 的项目突出显示
Posted
技术标签:
【中文标题】Android - 单击后保持 ListView 的项目突出显示【英文标题】:Android - Keep ListView's item highlighted once one has been clicked 【发布时间】:2012-03-06 01:31:48 【问题描述】:所以我有一个包含 2 个 ListView
小部件的活动,当您在第一个小部件中选择一个值时,第二个将填充与第一个 ListView
中的选择相关的值。这个机制没有问题,但现在我希望用户选择保持突出显示。我已经阅读了大量与该主题相关的问题,似乎有无数种方法可以实现这一点,但在尝试了大约 4-5 次之后,我仍然无法让它发挥作用。
我已经使用android:listSelector="#CCCCCC"
XML 属性在第二个ListView
上工作了,但是一旦将OnItemClickListener
引入到组合中(就像我在第一个@ 987654328@).
到目前为止,这是我所拥有的:
自定义OnItemClickListener
我发现浏览了有关此主题的各种答案(稍作修改以使其在第二个 ListView 中加载我的信息):
private class ItemHighlighterListener implements OnItemClickListener
private View oldSelection = null;
public void clearSelection()
if(oldSelection != null)
oldSelection.setBackgroundColor(android.R.color.transparent);
public void onItemClick(AdapterView<?> parent, View view, int pos, long id)
clearSelection();
oldSelection = view;
view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));
loadClubs(mXMLPortalOptions.getRegion(pos).getId());
mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));
这是我的list_selector.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"><shape>
<solid android:color="#CCCCCC" />
</shape></item>
<item android:state_selected="false"><shape>
<solid android:color="#FFFFFF" />
</shape></item>
</selector>
调用并执行方法(OnItemClick),但我的ListItem
的背景颜色保持不变:/
我不敢相信这个简单的任务竟然如此复杂。
如果我省略了可能有用的代码,或者我的问题缺乏细节,请随时指出,我会尽力解释自己。
【问题讨论】:
我认为这与您使用的SDK版本有关。 API 级别 7 是我正在使用的。 i.masm 的帖子有一个链接到我的想法。 android-developers.blogspot.com/2008/12/touch-mode.html 也许这会有所帮助:***.com/questions/15344320/… 【参考方案1】:为所选项目放置一个位置变量。更改onItemClicked()
方法中的位置。查看getView()
内List Adapter中选中的位置,并设置选中项的背景。
public class TestAdapter extends BaseAdapter
private Context context;
private ArrayList<TestList> testList;
private int selectedIndex;
private int selectedColor = Color.parseColor("#1b1b1b");
public TestAdapter(Context ctx, ArrayList<TestList> testList)
this.context = ctx;
this.testList = testList;
selectedIndex = -1;
public void setSelectedIndex(int ind)
selectedIndex = ind;
notifyDataSetChanged();
@Override
public int getCount()
return testList.size();
@Override
public Object getItem(int position)
return testList.get(position);
@Override
public long getItemId(int position)
return position;
private class ViewHolder
TextView tv;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View vi = convertView;
ViewHolder holder;
if(convertView == null)
vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);
holder = new ViewHolder();
holder.tv = (TextView) vi;
vi.setTag(holder);
else
holder = (ViewHolder) vi.getTag();
if(selectedIndex!= -1 && position == selectedIndex)
holder.tv.setBackgroundColor(Color.BLACK);
else
holder.tv.setBackgroundColor(selectedColor);
holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());
return vi;
现在在单击列表项时设置 selectedIndex 变量。
public class TestActivity extends Activity implements OnItemClickListener
// Implemented onItemClickListener
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
adapter.setSelectedIndex(position);
【讨论】:
你能详细解释一下吗.. 我得到了一些东西,但不是 100%。所以请详细说明步骤..请 很好的解释 - 几个新概念都一口气解释了,谢谢! 伟大而简单,这就是我喜欢我的代码的地方!直到我将一些东西设为静态并移动了一些东西(见下面我的回答),我才让它工作。 +1 您好,我正在尝试将这种方法与可扩展的列表视图一起使用,但无法使其正常工作,每当我打开一个组时,我发现其中选择了一个项目 @R4j 它不应该让你的 UI 变慢。也许还有其他原因。每次notifyDataSetChanged()
调用时,只会更新可见的行数。【参考方案2】:
要扩展 Shaiful 的出色解决方案,您可能无法让他在您的情况下发挥作用。
如果您正在使用将代码全部放在public void onListItemClick(ListView l, View v, int index, long id)
中,如果您正在使用片段并且必须声明一个接口而不是实现 OnListItemClickListener,或者导致您的 IDE 生成错误的任何原因,您可能必须访问变量和静态方法。
public static int selectedPosition = 0;
ArrayAdapter<Your_obj> adapter = null;
@Override
public void onListItemClick(ListView l, View v, int index, long id)
super.onListItemClick(l, v, index, id);
selectedPosition = index;
Your_adapter.setSelectedIndex(selectedPosition);
adapter.notifyDataSetChanged();
在 Your_adapter 中:
private static int selectedIndex;
//public Your_adapter...
public static void setSelectedIndex(int ind)
selectedIndex = ind;
@Override
public View getView(int position, View convertView, ViewGroup parent)
WellHolder holder = null;
if (null == convertView)
//set up your "holder"
if (position == selectedIndex)
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));
else
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));
return convertView;
其他一些区别是您不必将任何变量初始化为“0”或“-1”,并且在您的活动中调用 notifyDataSetChanged()。
再次感谢@Shaiful 的解决方案。它确实帮助我节省了尝试让 ios 中的默认设置适用于 Android 的时间,同时避免选择器/项目/聚焦/按下/等。
【讨论】:
这是因为你没有使用状态列表,这是一个低效且不太合适的解决方案,最好依靠这种东西的平台【参考方案3】:我遇到了类似的问题。这就是我的解决方案:
首先将自定义列表选择器添加到您的列表视图中:
<ListView
android:id="@+id/list"
android:layout_
android:layout_
android:listSelector="@drawable/listselector" />
在listselector.xml里面:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_accelerated="false"
android:drawable="@drawable/bg" />
</selector>
最后是带有高亮颜色的可绘制 bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33b5e6"/>
</shape>
【讨论】:
【参考方案4】:我认为最好和最简单的解决方案就是这个。您不需要在 ListView 本身上设置任何 android:listSelector
或对适配器进行任何更改。您不需要甚至需要调用OnItemClickListener
中的任何setSelection(position)
,因为它会自动处理。
设置为您的 ListView:
android:choiceMode="singleChoice"
设置列表项本身的背景:
android:background="?android:attr/activatedBackgroundIndicator"
就是这样。
这样您将获得默认的系统行为。这就是在默认的android.R.layout.simple_list_item_activated_1
布局中完成的方式。
【讨论】:
【参考方案5】:lv.setSelector(R.drawable.highlighter);
将highlighter.png
图像放入可绘制文件夹
在列表视图中突出显示所选项目的最简单方法。
【讨论】:
【参考方案6】:两周前我正在寻找它,结果是可绘制选择器无法实现。 欲了解更多信息,请阅读 Android 开发者博客中的这篇文章:Touch Mode
在简历中:只有当您的手指在屏幕上时,才会选择项目。
另一种可能性是保存在 var 中选择的项目,并使用您的自定义适配器绘制不同的颜色,就像 Shaiful 说的那样。
【讨论】:
【参考方案7】://create a list_itemselectorin drawable folder
//you will get the list item selected background color change once you select //the item
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused State -->
<item android:state_focused="true"><shape>
<solid android:color="#66FFFFFF" />
</shape></item>
<!-- Pressed State -->
<item android:state_pressed="true"><shape>
<solid android:color="@color/Black" />
</shape></item>
<!-- Default State -->
<item><shape>
<solid android:color="@color/Black" />
</shape></item>
</selector>
//create a list in layout folder
<ListView
android:id="@+id/mySlidingList"
android:layout_
android:layout_
android:choiceMode="singleChoice"
android:divider="@color/GrayHot"
android:dividerHeight="1dip"
android:listSelector="@drawable/list_itemselector"
android:scrollbars="none" />
// 并查看输出。
【讨论】:
【参考方案8】:如果你可以使用drawable来显示listItem Highlighted,那么你应该使用以下代码:-
listView.setSelector(R.drawable.bg_image);
有效。
【讨论】:
【参考方案9】:有一个简单的完全 XML 解决方案,它对我有用。 首先,使用选择器代码定义 XML-drawable,其中“正常”状态将对应于列表项的“选定未按下”视觉状态,而 state_pressed=true 对应于“按下”视觉状态。 文件“custom_item_selector.xml”示例,类似于 Holo 蓝色选择:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid
android:color="#643292ff">
</solid>
<stroke
android:
android:color="#c83292ff">
</stroke>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid
android:color="#323292ff">
</solid>
<stroke
android:
android:color="#783292ff">
</stroke>
</shape>
</item>
</selector>
(也可以在那里设置焦点状态)。 其次,将此 xml-drawable 应用为 ListView 的 listSelector 并设置它所需的选择模式:
<ListView
android:layout_
android:layout_
android:id="@+id/listView"
android:choiceMode="singleChoice"
android:listSelector="@drawable/custom_item_selector"/>
就是这样。它允许为“简单选定”和“按下选定”项目定义不同的视觉状态,例如使项目在按下时更亮。
【讨论】:
【参考方案10】:要保持列表项(多选)突出显示,单击(激活)时,请按照以下步骤操作。
1.将背景设置为可绘制的列表项布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@drawable/list_item_selector">
<ImageView
android:id="@+id/icon"
android:layout_
android:layout_
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="@mipmap/ic_launcher" >
</ImageView>
<TextView
android:id="@+id/label"
android:layout_
android:layout_
android:text="@+id/label"
android:textSize="20px" >
</TextView>
</LinearLayout>
2。可绘制选择器
<?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_red_light" />
<item android:state_activated="true" android:drawable="@android:color/holo_orange_dark" />
</selector>
3. Listview设置多选模式
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
按下时:
下图显示,当用户选择多个列表项时。
激活时:
【讨论】:
【参考方案11】:为了总结这篇文章并可能在将来帮助其他人,我建议答案:)
首先,我们需要创建res/drawable/list_item_background.xml
文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:drawable="@color/list_item_activated" />
<item
android:drawable="@color/list_item_default" />
</selector>
当然,请指定您的可绘制资源。您还可以添加其他具有不同状态的<item>
元素,例如state_pressed
、state_focused
等。
然后,我们应该将background
参数设置为我们的自定义列表项ViewGroup
元素(f.i. res/layout/list_item_layout.xml
),如下所示:
android:background="@drawable/list_item_background"
下一步是修改我们的自定义Adapter
类。以下是以下代码片段:
public class CustomAdapter extends BaseAdapter
private List<Item> items;
private LayoutInflater itemInflater;
private int selectedIndex; // add this
public CustomAdapter(Context c, List<Item> items)
this.items = items;
this.itemInflater = LayoutInflater.from(c);
selectedIndex = -1; // add this
/* add this */
public void setSelectedIndex(int index)
selectedIndex = index;
notifyDataSetChanged();
/* other adapter's stuff */
@Override
public View getView(int position, View convertView, ViewGroup parent)
if(convertView == null)
convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
// add this
convertView.setActivated(selectedIndex != -1 && position == selectedIndex);
/* do some stuff */
return convertView;
最后,我们应该在AdapterView.OnItemClickListener
的onItemClick(...)
方法中调用setSelectedIndex(position)
适配器的方法。
public class YourActivity extends Activity
implements AdapterView.OnItemClickListener
private CustomAdapter mCustomAdapter;
/* activity implementation */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
mCustomAdapter.setSelectedIndex(position);
现在,我们可以对适当的列表项突出显示感到满意了 :)
附:如果我们想在我们的列表中启用多项选择模式,我们只需将以下字符串放入保存listView
实例的活动类:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
因此,我们将获得正确的多个项突出显示。
-- 希望这对任何人都有帮助:)
【讨论】:
以上是关于Android - 单击后保持 ListView 的项目突出显示的主要内容,如果未能解决你的问题,请参考以下文章
在Android中通过ArrayAdapter在ListView中单击单个ImageView背景后如何更改它?
ListView OnClickItems 在 Android 中更改项目颜色
回到之前的片段(如 ListView)后,我可以保持 ScrollView 的位置吗?