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


76

我有XML两个ListView,一个包含由选择查询(lv_cli)填充的客户端列表,另一个包含所选择的客户端的详细信息(lv_cli_det)。我想lv_clilv_cli_det显示细节的同时让客户保持选中状态。

XML:

<ListView
    android:id="@+id/cli_lista"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:fadeScrollbars="false"
    >
</ListView>

<ListView
    android:id="@+id/cli_lista_det"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    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(); 
    }
});

显示您的代码。您使用片段还是什么?
Avinash Kumar Pankaj

只是做反向。您如何为highligh listview编写代码?邮编这里..
Dhaval帕尔马

Answers:


133

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

android:background="@drawable/bg_key"

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

<?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 / pressed_color”)。错误:错误:找不到与给定名称匹配的资源(在'drawable'处,值为'@ color / default_color')。
Celta 2013年

1
颜色名称只是示例。它表明您可以1)创建png格式的9patch彩色图像,然后将其放入drawable文件夹中,或者2)您可以在res / values / colors.xml中定义颜色,然后使用android:drawable =“ @颜色/您的颜色”。如果不存在,则需要首先创建colors.xml。
Neoh

第一个列表视图是否正常工作?您需要对第二个列表视图的布局xml及其onClickListener()执行相同的操作
Neoh,2013年

我不需要第二个Listview像第一个一样
Celta

我只看到在您的代码中定义了一个listView td。您不应该定义两个列表视图吗?
Neoh

165

我找到了正确的方法。非常简单 在资源中描述以下内容:

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和更改视图背景进行PS操作已破产,因为视图本身是一个临时对象。因此,您不得跟踪视图。

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


15
这应该被接受。简单高效。
Chostakovitch 2015年

2
简单优雅的答案!
黑暗骑士

1
尽管其他答案是正确的,但这是干净而简单的。
velval 2015年

1
我要默认选择一个listView项,该怎么办?
Apurva '16

3
@AJG如果我将模式从单人更改为多人,则无法使用。它仅显示最后选择的彩色项目。但是我想要,如果我选择三个项目,那么所有三个项目都必须着色。
Ajay Sharma

37
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将当前选定的元素保存在全局变量中。


6
显示键盘时发生奇怪的事情。发生多重选择。
里卡多

1
这是错误的,因为列表视图为了节省内存,似乎使用相同的视图,每10个项目使用一个视图(或者可能是每个n个项目,其中n大于屏幕上可见的项目数)。这就是为什么发生多选的原因。
marco

13

简单的方法是,如果您在xml中使用列表视图,请在列表视图中使用此属性,

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

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

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

10
你来晚了 AJG的答案比您的答案早一年,而且更完整。
SMBiggs

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。


不要忘记android:listselector="@drawable/my_selector"在您的ListView中添加以下行:
SMBiggs

此解决方案在Android Kitkat 19中对我
有用。

2

以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”

毛罗


2

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

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

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>

这些之后

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


1

一种方法是跟踪活动中当前选择的位置:

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

现在,请确保将ID分配给列表项的父级布局(linearLayout,boxLayout,relativeLayout等。)。

然后,您可以在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);
}

基本上,您只需在背景色等于当前选定位置时将背景色设置为背景即可。请注意,当未选中该项时,如何设置可绘制背景资源。在您的情况下,这可能有所不同(因为您未发布代码)。就我而言,此可绘制对象是一个选择器,可确保按下时使该项目高亮显示。

注意:此简单代码不使用视图持有者,但我确实建议使用一个视图持有者。


0

使用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();
.....
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.