ListView Clicked Item Highlight not working properly

I have a ListView and have a onClickListener for this ListView. ListView is using the SimpleAdapter, and populating the Data via a map.

Whenever Item is clicked, that List Item is getting highlighted. But the problem is, Suppose I click the 4th Item on the List and scroll the list, then every 4th element is highlighted. I'm using a Selector xml to implement the highlight functionality

I know the problem is due to the screen refresh.

But how can I avoid this problem? Searching for the answers from about a month now. I need a solution now.

Thanks in advance.

Selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/drawer_icon_normal" android:state_selected="false" android:state_pressed="false"/>
    <item android:drawable="@drawable/drawer_icon_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/drawer_icon_activated" android:state_selected="true"/>
</selector>

Below is the code for populating the listView and onclick functionality. //Note this code is not using the selector, how with this code also, functionality is same.

public void populateListView() {
        //Populate the List View Here

        //Set the adapter       
        SimpleAdapter flvadapter = new SimpleAdapter(getActivity(), finalSongList, android.R.layout.simple_list_item_1, new String[]{"filename"}, new int[]{android.R.id.text1});

        fileListView.setAdapter(flvadapter);

        fileListView.setBackgroundColor(Color.WHITE);
        fileListView.setTextFilterEnabled(true);
        fileListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        //Registering the OnItemClicklistener
        fileListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {

                //TODO Auto-generated method stub
                //fileListView.getItemAtPosition(position);

               updateView(position);

                index = position;
                @SuppressWarnings("unchecked")
                HashMap<String, String> hm = (HashMap<String, String>) fileListView.getItemAtPosition(position);
                if (hm.get("fileuri") == null) {
                    AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
                    adb.setTitle("ListView OnClick");
                    adb.setMessage("Selected Item is = " + hm.get("fileuri"));
                    adb.setPositiveButton("Ok", null);
                    adb.show();
                } else {
                    //Processing the Selected File
                }
            }
        });
    }

private void updateView(int index){
        //View v=fileListView.getChildAt(index-fileListView.getFirstVisiblePosition());
        selectedListViewItem=fileListView.getChildAt(index);
        fileListView.setBackgroundColor(Color.WHITE);
        if (selectedListViewItem != null) {
            selectedListViewItem.setBackgroundColor(Color.CYAN);
        }
    }

Answers


In your updateView() function, you are changing the selectedListViewItem's background color. up to this point everything works like you would assume however when you scroll, every so ofter another row will already be "selected" even though you didn't do it yourself.

That is caused by view recycling, a function of Listview adapters that allow them to load faster by taking a row that has been scrolled out of the screen, fill it with new data and present it as is (without needing to inflate it from XML again.

Basically it will take your old blue row that is not on the screen anymore, put a new string in and display it as the new row.

The way you fix it is by implementing your own Adapter and overriding the getView method. there are a ton of resources that will show you how to do that. Here is one

One thing to keep in mind, once you implement your custom Adapter is that you will have to keep track of which items have been clicked so you can un-highlight and re-highlight items correctly.


you are changing the background color of the selected item but not reset it in the adapter

try to post your adapter code

so check in adapter getView method

if item is selected setBackgroudColor for selected row else setBackgroundColor for normal row


Need Your Help

How to parameterize a boolean expression in Linq?

asp.net-mvc linq

I have a Linq statement that looks something like:

Best Way to Store/Access a Directed Graph

rdbms common-table-expression directed-graph

I have around 3500 flood control facilities that I would like to represent as a network to determine flow paths (essentially a directed graph). I'm currently using SqlServer and a CTE to recursively