Android ListView selected item stay highlighted
Asked Answered
L

9

78

I have an XML with two ListView, one with a list of clients filled by a select query (lv_cli) and the other with the details of the client selected (lv_cli_det). I would like to keep the client selected in the lv_cli while the lv_cli_det show the details.

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(); 
    }
});
Lorelle answered 24/4, 2013 at 10:29 Comment(3)
show your code. you used fragment or what??Operator
just do reverse. how you do code for highligh listview?? post code here..Trauner
https://mcmap.net/q/263240/-set-highlighted-item-in-gridview-on-androidTooling
K
138

To hold the color of listview item when you press it, include the following line in your listview item layout:

android:background="@drawable/bg_key"

Then define bg_key.xml in drawable folder like this:

<?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>

Finally, include this in your ListView onClickListener:

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

This way, only one item will be color-selected at any time. You can define your color values in res/values/colors.xml with something like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>
Kettledrummer answered 24/4, 2013 at 10:59 Comment(11)
error: Error: No resource found that matches the given name (at 'drawable' with value '@drawable/ pressed_color'). error: Error: No resource found that matches the given name (at 'drawable' with value '@color/default_color').Lorelle
The color name is just example. It shows that you can either 1) create a 9patch color image in png format then put it inside drawable folder, or 2)you can define the color in res/values/colors.xml, then call it with android:drawable="@color/yourcolor". You will need to create the colors.xml first if it does not exist.Kettledrummer
Does the first listview work properly? You need to do the same thing for the second listview's layout xml and its onClickListener()Kettledrummer
i dont need the second listview to act like the firstLorelle
I only see one listView td being defined in your code. Shouldn't you define two listview's?Kettledrummer
if you want standard color, use 9png <item android:drawable="@drawable/list_selector_background_transition_holo_light" android:state_pressed="true"/> insteadKermis
hey @Neoh, what is that "@drawable/bg_key" refer to? I didnt see it the resource here....Mihalco
Hi, i also used this solution and it seemed to work at first, but when the list got longer, i found that the background color of the selection disappears if i scroll away. Is there any way to fix that?Denmark
If you need longer list then you should use viewholder pattern. I'm afraid that is out of the scope of this question.Kettledrummer
I found this linked answer a simpler and better solution.Augean
This method should write into android official document.Lemley
T
171

I found the proper way. It's very simple. In resource describe following:

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

(or you may specify a resource link instead of color value)

Programmatical:

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

mode can be one of these: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (default)

(AbsListView is the abstract ancestor for the ListView class)

P.S. manipulations with onItemClick and changing view background are bankrupt, because a view itself is a temporary object. Hence you must not to track a view.

If our list is long enough, the views associated with scrolled out items will be removed from hierarchy, and will be recreated when those items will shown again (with cached display options, such as background). So, the view we have tracked is now not an actual view of the item, and changing its background does nothing to the actual item view. As a result we have multiple items selected.

Torn answered 5/8, 2014 at 4:17 Comment(4)
I want one of the listView item selected by default, how can I do that?Lesslie
I finally found you my saver!!!! :D, you might add that these lines goes in the XML activity here (for newbies like me! :D) <ListView ... android:choiceMode="singleChoice" android:listSelector="#666666" ... />Ewart
@Torn If I change mode to single to Multiple , it not works. It shows only last one selected item colored. But I want that If I select three items then all three must be colored.Diadem
listView.setSelector(Drawable selector) this methode saved meFederation
K
138

To hold the color of listview item when you press it, include the following line in your listview item layout:

android:background="@drawable/bg_key"

Then define bg_key.xml in drawable folder like this:

<?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>

Finally, include this in your ListView onClickListener:

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

This way, only one item will be color-selected at any time. You can define your color values in res/values/colors.xml with something like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>
Kettledrummer answered 24/4, 2013 at 10:59 Comment(11)
error: Error: No resource found that matches the given name (at 'drawable' with value '@drawable/ pressed_color'). error: Error: No resource found that matches the given name (at 'drawable' with value '@color/default_color').Lorelle
The color name is just example. It shows that you can either 1) create a 9patch color image in png format then put it inside drawable folder, or 2)you can define the color in res/values/colors.xml, then call it with android:drawable="@color/yourcolor". You will need to create the colors.xml first if it does not exist.Kettledrummer
Does the first listview work properly? You need to do the same thing for the second listview's layout xml and its onClickListener()Kettledrummer
i dont need the second listview to act like the firstLorelle
I only see one listView td being defined in your code. Shouldn't you define two listview's?Kettledrummer
if you want standard color, use 9png <item android:drawable="@drawable/list_selector_background_transition_holo_light" android:state_pressed="true"/> insteadKermis
hey @Neoh, what is that "@drawable/bg_key" refer to? I didnt see it the resource here....Mihalco
Hi, i also used this solution and it seemed to work at first, but when the list got longer, i found that the background color of the selection disappears if i scroll away. Is there any way to fix that?Denmark
If you need longer list then you should use viewholder pattern. I'm afraid that is out of the scope of this question.Kettledrummer
I found this linked answer a simpler and better solution.Augean
This method should write into android official document.Lemley
L
38
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);
});

Perhaps you might want to save the current selected element in a global variable using the index i.

Luminance answered 26/11, 2013 at 10:23 Comment(2)
Something weird happens when the keyboard is showed. a Multi selection occurs.Surrey
This is wrong as the listview, to save memory, seems to be using the same views each 10 items (or probably each n items where n is bigger than the number of items visible on the screen). That's why multi selection occurs.Acquaintance
S
15

Simplistic way is,if you are using listview in a xml,use this attributes on your listview,

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

if not using xml,by programatically

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);
Seaplane answered 23/10, 2015 at 10:21 Comment(1)
You're a little late. AJG's answer pre-dates yours by over a year and is more complete.Pasadis
S
5

You need selector like this:

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

And then set android:choiceMode="singleChoice" to your ListView.

Silicone answered 18/11, 2014 at 10:20 Comment(2)
Don't forget to add the line: android:listselector="@drawable/my_selector" in your ListView!Pasadis
This solution works for me in Android Kitkat 19 Thanks alotGudren
C
2

From Avinash Kumar Pankaj's example

View v;

then at oncreate method

v = new View(getActivity());

and then onlistitemclick method i wrote

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

It worked for me. Thank you.

I replaced

v = new View(getActivity());

to

v = new View(this);

and the code worked well.

It is necessary the xml files 'colors' and 'bg_key' from previous examples too, as well as ListView attribute android:background="@drawable/bg_key"

Mauro

Cosgrave answered 28/10, 2013 at 10:6 Comment(0)
F
2

*please be sure there is no Ripple at your root layout of list view container

add this line to your list view

android:listSelector="@drawable/background_listview"

here is the "background_listview.xml" file

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

the colors that used in the background_listview.xml file :

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

after these

(clicked item contain orange color until you click another item)

Fishback answered 24/11, 2015 at 7:17 Comment(0)
D
1

One way you can do this, is to Keep track of the current selected position in your activity:

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

Now, be sure you assign an ID to the parent layout (linearLayout, boxLayout, relativeLayout, .. Whatever you prefer) of your list item.

Then in your ListView you can do something Like this:

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);
}

Basically, you just set the hilight color to the layout as a background when it equals your current selected position. Notice how I set a drawable background resource when the item is not selected. This could be in your case different (since you posted no code). In my case, this drawable is a selector which makes sure the item is hi-lighted when pressed.

NOTE: This simple code doesn't use a view-holder, but I really recommend using one.

Dunker answered 24/4, 2013 at 11:2 Comment(0)
K
0

Use the id instead:

This is the easiest method that can handle even if the list is long:

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;
}

And then in your 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();
.....
Kolnos answered 29/6, 2016 at 7:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.