setSelection not changing ListView position

I am having some trouble with the ListView setSelection method. I am attempting to have my list view remain at the same index when switching between landscape and portrait orientation. However, every time I rotate and the activity is recreated, the listview starts at the top. The code I am using is as follows:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = new ArrayList<Integer>();
    for (Integer i : f_checkedMessages) {
        indices.add(i);
    }
    savedInstanceState.putIntegerArrayList("CheckedMessageIndices", indices);
    savedInstanceState.putInt("ListIndex", f_listView.getFirstVisiblePosition());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = savedInstanceState.getIntegerArrayList("CheckedMessageIndices");
    for (Integer i : indices) {
        f_checkedMessages.add(i);
    }
    int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.setSelection(listIndex);
}

I have used the debugger to verify that listIndex is the correct value. It should also be mentioned that the checked listview items persist when changing orientation. I know that setSelected only SELECTS the listview item if in touch mode, but the documentation says that this method will align the listview regardless of whether in touch mode or not.

Does anyone know why this is not working or if there is a better way of going about this?

Thanks, your help is much appreciated!

Answers


If further help, after a few hours lost with this problem, I managed to solve it using the same example of A-IV, with some modifications.

First of all, it is essential that the method clearFocus() is called before execute the runnable.

Devices that have just as touch mode controller has no visual effect when the method setSelection(index) is called, but the item will normally be selected. Therefore, it is necessary to call requestFocusFromTouch() to enable visual changes caused by the method setSelection(index).

After calling the setSelection(index), call the requestFocus() so that to give focus to view.

@Override public void onRestoreInstanceState(Bundle savedInstanceState) {
...
final int listIndex = savedInstanceState.getInt("ListIndex");
f_listView.clearFocus();
f_listView.post(new Runnable() {
    @Override
    public void run() {
        listView.requestFocusFromTouch();
        listView.setSelection(listIndex);
        listView.requestFocus();
    }
});

}

I hope I helped!


You can use below code for solve this problem

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    listView = getListView();
    listView.setAdapter(adapter);

    listView.post(new Runnable()
    {
        public void run()
        {
            listView.setSelection(position);
        }
    });
} 

OR

listView.setAdapter(adapter);
listView.setSelection(position);
adapter.notifyDataSetChanged(); 

OR Please refer following link:

http://www.codeproject.com/Tips/514527/ListActivity-setSelection-within-onCreate

I hope you will get solution. Thank You


You can't set selection directly after data has been changed. Try this:

@Override public void onRestoreInstanceState(Bundle savedInstanceState) {
    ...
    final int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.post(new Runnable() {
        @Override
        public void run() {
            listView.setSelection(listIndex);
        }
    });
}

Maybe you should use "smoothScrollToPosition(int position)" if you are in the SDK level >= 8.


The problem for me was that i call adapter.notifyDataSetChanged(); after calling mListView.setSelection(0);

now i am calling in this order:

 adapter.notifyDataSetChanged();
 mListView.setSelection(0);

and it's working.


If your ListView is inside a ListFragment, just call setSelection().


The only solution that worked for me was:

    mListView.postDelayed(new Runnable() {
        @Override
        public void run() {
            mListView.setSelection(index);
        }
    }, 300);

Looks awful, but this way it works in both touch and non-touch modes.


I think I found the best solution without using post a Runnable:

list.setAdapter(adapter);
list.setSelection(list.getCount() - 1);

use this code,

sp2.setAdapter(sp2.getAdapter());
        sp2.getAdapter().notifyDataSetChanged();
        sp2.setSelection(0, false);

Need Your Help

MySQL FULLTEXT not working

mysql full-text-search myisam

I'm attempting to add searching support for my PHP web app using MySQL's FULLTEXT indexes.

Accessing an Artifactory/Maven Repo that requires basic-auth

maven-2 basic-authentication artifactory

I have an Artifactory repo that sits behind basic authentication. How would I configure the settings.xml to allow access?