开发者

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 o开发者_Go百科nRestoreInstanceState(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!


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜