Highlight selected item in ListView on Android
Asked Answered
T

7

8

I have been making an application that works with ListViews in Android, and I can't make it so that the selected (chacked) item has a different background. I'm using CHOICE_MODE_SINGLE. This is how my code looks so far:


The ListView that I use:
(inside layout.xml)

<ListView
    android:id="@+id/listView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:choiceMode="singleChoice"
    android:listSelector="@drawable/selector_test" >
</ListView>

The TextView layout I use in the adapter:
(listItem.xml)

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="23sp"
    android:textStyle="bold" />

This is where I add the adapter:

mListAdapter = new ArrayAdapter<String>(this, R.layout.listItem, mList);
mListView = (ListView) findViewById(R.id.listView);
mListView.setAdapter(mAuthorAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        String selected = mList.get(position);
        // ...
        mListView.setItemChecked(position, true);
    }
});

I'm sure that the proper item is checked on click, because when I call getCheckedItemPosition(), it returns the proper value.


And now, the two things I tried in order to highlight the checked item:


Selector drawable:
(selector_test.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="@android:integer/config_longAnimTime">

    <item android:state_checked="true"><shape>
            <solid android:color="@color/red" />
        </shape></item>
    <item android:state_selected="true"><shape>
            <solid android:color="@color/blue" />
        </shape></item>
    <item android:state_pressed="true"><shape>
            <solid android:color="@color/green" />
        </shape></item>

</selector>

I add it to .xml with:

android:listSelector="@drawable/selector_test"

Background drawable:
(background_test.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/red" android:state_checked="true"/>
    <item android:drawable="@color/blue" android:state_selected="true"/>
    <item android:drawable="@color/green"/>

</selector>

I add it to .xml with:

android:background="@drawable/background_test"

I've tried adding the selector and the background to both listView.xml and listItem.xml, but the only thing that changes is the default background color, and the color of the selector when the item is pressed (or held).
android:state_checked="true" and android:state_selected="true" seem to do nothing.

I can change the background by overriding the getView() method in ArrayAdapter and invoking setBackgroundColor() in it if the view is selected, and it does change the background, but also gets rid of the selector entirely. Also, I don't really like to override classes just to change one line of code, especially if that same thing can be achieved in a different way.

So what I'm asking is, is there a way to highlight checked item in ListView by adding a selector or background drawable to it, and I am just doing it wrong, or will I have to make it work some other way.

Thanks in advance! :)

Trilbee answered 3/3, 2014 at 18:24 Comment(0)
C
8

add this line in onStart of your activity

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

where lv is instance of listView

then override this method and add the following lines to it.

 @Override
public void onListItemClick(ListView l, View v, int position, long id) {


    // Set the item as checked to be highlighted 
    lv.setItemChecked(position, true);
            v.setBackgroundColor(Color.BLUE);

        conversationAdapter.notifyDataSetChanged();

}

and then change the color of previous selected item's background back to normal in getView method of your custom adapter

Cockfight answered 3/3, 2014 at 18:39 Comment(3)
As I've said, the correct item is checked, it's just that it's background doesn't change.Trilbee
Hi Velja, I have made some changes in my answer, hope i'll be helpful to you.Cockfight
what is the normal background color? @RavinderBhandari i cannot give a null on that method.Checky
H
5

Try this:

listViewDay.setItemChecked(position, true);
listViewDay.setSelection(position);

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="40dp"
    android:background="@drawable/list_day_selector" >

    <TextView
        android:id="@+id/txtItemDay"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="22"
        android:textColor="@android:color/white"
        android:textSize="22sp" />

</LinearLayout>

list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/list_item_bg_normal" android:state_activated="false"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_pressed="true"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_activated="true"/>

</selector>
Holbrooke answered 4/3, 2014 at 7:44 Comment(3)
the activated state is giving me error alert .... is there something missing? @JackDuongChecky
the error i obtained is here: "This item is unreachable because a previous item (item #1) is a more general match than this one"Checky
I think you wanted to call the 2. XML file list_day_selector.xml.Merrimerriam
M
3

Programmatically, use setSelector. For example:

lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);
Madelyn answered 15/11, 2015 at 2:17 Comment(1)
This is what most people is searchingPolemic
F
0

After some hours of encountering one glitch after another (including the selector leaving a dirty stripe), I decided to do it myself:

class MyListAdapter extends ArrayAdapter<MyData> {
    // !!! access to the current selection
    int mSelected = 0;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v =  super.getView(position, convertView, parent);
        // !!! this is where the selected item is highlighted
        v.findViewById(R.id.selectionSign).setVisibility(position == mSelected ? View.VISIBLE : View.INVISIBLE);
        return v;
    }
    public CommandListAdapter(Context context, List<MyData> objects) {
        super(context, R.layout.mylistitem, R.id.mytext, objects);
    }
}

with the OnItemClickListener:

        mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                setSelectionPosNoUpd(position);
                update();
            }
        });

and the functions defined as:

    void setSelectionPosNoUpd(int n) {
        mCommandListAdapter.mSelected = n;
        //update();
    }
    void update() {
        mListViewOfCommands.smoothScrollToPosition(getSelectionPos());
        mCommandListAdapter.notifyDataSetChanged();
    }

and the list item XML (res/layout/mylistitem.xml) is:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mytext" 
        />
    </LinearLayout>
    <View
        android:id="@+id/selectionSign"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#10ff5000"
        android:visibility="invisible"
        />
</FrameLayout>

The downside is that after changing the selection I have to update(): there is no easy way to unhighlight the previously highlighted view.

Fabre answered 2/4, 2015 at 14:0 Comment(0)
L
0

Set item state in selector like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true"
        android:color="@color/XXX/>
</selector>

I don't know why state_checked not working. At first I thought it must be a Checkableview then I tried CheckedTextView. Still not working.
Anyway, state_activated will solve the problem.

Lashley answered 30/4, 2015 at 7:43 Comment(0)
C
-1

I think you cann't use mListView inside anonymous class. You must use AdapterView arg0

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View view,
                int position, long id) {
            AnyObject obj=(AnyObject)arg0.getItemAtPosition(position);

                            ........
                            .........
                            .........

        }
    });
Chapa answered 29/4, 2014 at 15:16 Comment(0)
R
-1

This post has worked out for me: http://www.mynewsfeed.x10.mx/articles/index.php?id=14

The ListView (inside layout.xml):

<ListView
    android:id="@+id/list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/list_custom"
    android:choiceMode="singleChoice"/>

Selector drawable(list_custom.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/orange"/>
    <item android:state_activated="true" android:drawable="@color/blue" />
    <item android:drawable="@color/green" />
</selector>

Color.xml in values folder:

<resources>
    <item name="blue" type="color">#FF33B5E5</item>
    <item name="green" type="color">#FF99CC00</item>
    <item name="orange" type="color">#FFFFBB33</item>
</resources>
Repudiation answered 22/6, 2015 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.