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

Posted

技术标签:

【中文标题】Android ListView 所选项目保持突出显示【英文标题】:Android ListView selected item stay highlighted 【发布时间】:2013-04-17 20:47:08 【问题描述】:

我有一个XML 和两个ListView,一个包含由选择查询 (lv_cli) 填充的客户列表,另一个包含所选客户的详细信息 (lv_cli_det)。 我想在lv_cli 中选择客户端,而lv_cli_det 显示详细信息。

XML:

<ListView
    android:id="@+id/cli_lista"
    android:layout_
    android:layout_
    android:fadeScrollbars="false"
    >
</ListView>

<ListView
    android:id="@+id/cli_lista_det"
    android:layout_
    android:layout_
    android:layout_toRightOf="@+id/cli_lista"
    android:fadeScrollbars="false" >
</ListView>

Java:

Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);

final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems2);

t.setOnItemClickListener(new OnItemClickListener() 
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");

        cli.load(strArray[0].toString());
        td.setAdapter(myarrayAdapter2);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        listItems2.add("Localidade: " + cli.getLoca());
        listItems2.add("Código Postal: " + cli.getCp());
        listItems2.add("Pais: " + cli.getPais());
        listItems2.add("Nif: " + cli.getNif());
        listItems2.add("Tel: " + cli.getTel());
        listItems2.add("Tlm: " + cli.getTlm());
        listItems2.add("Tipo Preço: " + cli.getTipoPvn());
        listItems2.add("Cond. Pagamento: " + cli.getCpg());
        listItems2.add("Obs: " + cli.getObs());
        td.setAdapter(myarrayAdapter2);
        myarrayAdapter2.notifyDataSetChanged(); 
    
);

【问题讨论】:

显示您的代码。你用的是片段还是什么?? 只是反向操作。你如何为highligh listview编写代码?在这里发布代码.. ***.com/a/15898103/726863 【参考方案1】:

我找到了正确的方法。这很简单。 在资源中描述如下:

android:choiceMode="singleChoice"
android:listSelector="#666666"

(或者您可以指定资源链接而不是颜色值)

程序化:

listView.setSelector(Drawable selector);
listView.setSelector(int resourceId);
listView.setChoiceMode(int mode);

模式可以是以下之一:AbsListView.CHOICE_MODE_SINGLE、AbsListView.CHOICE_MODE_MULTIPLE、AbsListView.CHOICE_MODE_NONE(默认)

(AbsListView 是 ListView 类的抽象祖先)

附:使用 onItemClick 和更改视图背景的操作是破产的,因为视图本身是一个临时对象。因此,您不能跟踪视图。

如果我们的列表足够长,与滚动出的项目相关联的视图将从层次结构中删除,并在这些项目再次显示时重新创建(使用缓存的显示选项,例如背景)。因此,我们跟踪的视图现在不是项目的实际视图,并且更改其背景对实际的项目视图没有任何作用。因此,我们选择了多个项目。

【讨论】:

这应该是被接受的答案。简单而高效。 简单优雅的答案! 虽然其他答案都是正确的,但这个答案很简洁。 我想要默认选中的listView项目之一,我该怎么做? @AJG 如果我将模式更改为 single 到 Multiple ,它不起作用。它仅显示最后一个选定项目的颜色。但我希望如果我选择三个项目,那么所有三个项目都必须是彩色的。【参考方案2】:

要在按下时保持列表视图项的颜色,请在列表视图项布局中包含以下行:

android:background="@drawable/bg_key"

然后像这样在drawable文件夹中定义bg_key.xml

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

最后,将其包含在您的ListView onClickListener

listView.setOnItemClickListener(new OnItemClickListener() 
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) 
        view.setSelected(true);
        ... // Anything
    
);

这样,任何时候都只会选择一个项目的颜色。您可以在res/values/colors.xml 中定义您的颜色值,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>

【讨论】:

错误:错误:找不到与给定名称匹配的资源(在“drawable”处,值为“@drawable/pressed_color”)。错误:错误:未找到与给定名称匹配的资源(在“drawable”处,值为“@color/default_color”)。 颜色名称只是示例。它表明您可以 1)创建一个 png 格式的 9patch 彩色图像,然后将其放入可绘制文件夹中,或者 2)您可以在 res/values/colors.xml 中定义颜色,然后使用 android:drawable="@颜色/你的颜色”。如果colors.xml不存在,你需要先创建它。 第一个列表视图工作正常吗?您需要对第二个列表视图的布局 xml 及其 onClickListener() 执行相同的操作 我不需要第二个列表视图就可以像第一个一样 这个方法应该写入android官方文档。【参考方案3】:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 

            for (int j = 0; j < adapterView.getChildCount(); j++)
                adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

            // change the background color of the selected element
            view.setBackgroundColor(Color.LTGRAY);
);

也许您可能希望使用索引 i 将当前选定元素保存在全局变量中。

【讨论】:

显示键盘时会发生一些奇怪的事情。出现多选。 这是错误的,因为列表视图为了节省内存,似乎每 10 个项目使用相同的视图(或者可能每 n 个项目,其中 n 大于屏幕上可见的项目数)。这就是多选出现的原因。【参考方案4】:

简单的方法是,如果您在 xml 中使用 listview,请在您的 listview 上使用此属性,

android:choiceMode="singleChoice"
android:listSelector="#your color code"

如果不使用 xml,则通过编程方式

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);

【讨论】:

你来晚了。 AJG 的答案比你的早一年多,而且更完整。【参考方案5】:

你需要这样的选择器:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:drawable="@color/app_primary_color_light" android:state_pressed="true" />

<!-- Used when the view is "activated". -->
<item android:drawable="@color/app_primary_color" android:state_activated="true" />

<!-- Default, "just hangin' out" state. -->
<item android:drawable="@android:color/transparent" /></selector>

然后将 android:choiceMode="singleChoice" 设置为您的 ListView。

【讨论】:

不要忘记在您的 ListView 中添加行:android:listselector="@drawable/my_selector" 此解决方案适用于 Android Kitkat 19 非常感谢【参考方案6】:

来自 Avinash Kumar Pankaj 的示例

View v;

然后在 oncreate 方法

v = new View(getActivity());

然后我写的onlistitemclick方法

public void onListItemClick(ListView listView, View view, int position,
       long id) 
   v.setBackgroundResource(0);
   view.setBackgroundResource(R.color.green);
   v = view;

它对我有用。谢谢。

我换了

v = new View(getActivity());

v = new View(this);

而且代码运行良好。

前面例子中的xml文件'colors'和'bg_key'也是必须的,还有ListView属性android:background="@drawable/bg_key"

毛罗

【讨论】:

【参考方案7】:

*请确保列表视图容器的根布局中没有波纹

将此行添加到您的列表视图中

android:listSelector="@drawable/background_listview"

这里是“background_listview.xml”文件

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white_background" android:state_pressed="true" />
<item android:drawable="@color/primary_color" android:state_focused="false" /></selector>

background_listview.xml 文件中使用的颜色:

<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>

在这些之后

(单击的项目包含橙色,直到您单击另一个项目)

【讨论】:

【参考方案8】:

您可以这样做的一种方法是跟踪活动中当前选定的位置:

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) 
        currentPosition = position
        lv_cli.notifyDataSetChanged();
    

现在,请确保为列表项的父布局(linearLayout、boxLayout、relativeLayout 等)分配一个 ID。

然后在您的 ListView 中,您可以执行以下操作:

layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);

if (YourActivity.this.currentPosition == position) 
    layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
 else
    layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);

基本上,当它等于您当前选择的位置时,您只需将布局的高亮颜色设置为背景。 请注意我在未选择项目时如何设置可绘制背景资源。在您的情况下,这可能会有所不同(因为您没有发布代码)。在我的例子中,这个 drawable 是一个选择器,它确保项目在按下时是高亮的。

注意:这个简单的代码不使用视图持有者,但我真的 推荐使用一个。

【讨论】:

【参考方案9】:

改用 id:

这是最简单的方法,即使列表很长也可以处理:

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

【讨论】:

以上是关于Android ListView 所选项目保持突出显示的主要内容,如果未能解决你的问题,请参考以下文章

在android的listview中突出显示所选项目

Android - 单击后保持 ListView 的项目突出显示

在 ListView 中默认选择一行并突出显示所选行 Android

Android - 禁用 ListView 选择突出显示但保持启用 OnClick [重复]

ListView 项目在滚动后保持突出显示

ListView 保持选中状态?