Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 239
Chris Avatar asked Aug 10 '11 22:08

Chris


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

like image 83
Taynã Bonaldo Avatar answered Nov 08 '22 08:11

Taynã Bonaldo


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

like image 8
hharry_tech Avatar answered Nov 08 '22 07:11

hharry_tech


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);
        }
    });
}
like image 7
A-IV Avatar answered Nov 08 '22 06:11

A-IV