Android ListView setSelection() does not seem to work
AndroidListviewAndroid Problem Overview
I have a ListActivity
that implements onListItemClick()
and calls a doSomething()
function of the class. The latter contains l.setSelection(position)
where l
is the ListView
object.
Now there is a onClickListener()
listening for a button click that perfoms some actions and that too calls doSomething()
.
In the first case, the selected item get positioned appropriately, but in the latter, nothing happens.
Any clues about this strange behaviour and how I might make it work?
Android Solutions
Solution 1 - Android
maybe you need to use function:
ListView.setItemChecked(int position, boolean checked);
Solution 2 - Android
use requestFocusFromTouch()
before calling setSelection()
method
Solution 3 - Android
I know this is an old question but I just had a similar problem that I solved in this way:
mListView.clearFocus();
mListView.post(new Runnable() {
@Override
public void run() {
mListView.setSelection(index);
}
});
Solution 4 - Android
You might need to wrap setSelection()
in a post
ed Runnable
(reference).
Solution 5 - Android
setSelection()
does not necessarily have visual impact. The selection bar only appears if you use the D-pad/trackball to navigate the list. If you tap on the screen to click something, the selection bar appears briefly and vanishes.
Hence, setSelection()
will only have a visual impact if the activity is not in touch mode (i.e., the last thing the user did was use the D-pad/trackball).
I am not 100% certain this explains your phenomenon given the description you provided, but I figured it is worth a shot...
Solution 6 - Android
If you use an Adapter for your ListView add this code to your adapter:
public class MyAdapter extends
ArrayAdapter<MyClass> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflator = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflator.inflate(R.layout.my_adapter, null);
} else {
rowView = (View) convertView;
}
//...
// set selected item
LinearLayout ActiveItem = (LinearLayout) rowView;
if (position == selectedItem)
{
ActiveItem
.setBackgroundResource(R.drawable.background_dark_blue);
// for focus on it
int top = (ActiveItem == null) ? 0 : ActiveItem.getTop();
((ListView) parent).setSelectionFromTop(position, top);
}
else
{
ActiveItem
.setBackgroundResource(R.drawable.border02);
}
}
private int selectedItem;
public void setSelectedItem(int position) {
selectedItem = position;
}
}
In your Activity:
myAdapter.setSelectedItem(1);
Solution 7 - Android
For me calling
listView.notifyDataSetChanged();
listView.requestFocusFromTouch();
and then
listView.setSelection(position);
solved the issue.
if you do that in a runnable it works without calling requestFocusFromTouch(), but the old position of the ListView is showen for a sekound.
Solution 8 - Android
I have an very large Request with Webcontent. When I used the code in onCreateView the Listview wasnt even finished loading. I put it in onPostExecute of my AsyncTask.
//Get last position in listview
if (listView != null && scrollPosition != 0) {
listView.clearFocus();
listView.requestFocusFromTouch();
listView.post(new Runnable() {
@Override
public void run() {
listView.setItemChecked(scrollPosition, true);
listView.setSelection(scrollPosition);
}
});
}
Dont forget to set the item checked in on Click ;)
Solution 9 - Android
Maybe you should use the smoothScrollToPosition(int position) method of ListView
Solution 10 - Android
You can try 2 ways like these:
Solution A:
mListView.post(new Runnable() {
@Override
public void run() {
if (null != mListView) {
mListView.clearFocus();
mListView.requestFocusFromTouch();
mListView.setSelection(0);
}
}
});
In some complicated situation, this solution will bring some new problems in Android 8.x.
Besides it may cause unexpected onFocusChange().
Solution B: Define a custom view extends ListView. Override method handleDataChanged().Then setSelection(0). In CustomListView:
@Override
protected void handleDataChanged() {
super.handleDataChanged();
if (null != mHandleDataChangedListener){
mHandleDataChangedListener.onChanged();
}
}
HandleDataChangedListener mHandleDataChangedListener;
public void setHandleDataChangedListener(HandleDataChangedListener handleDataChangedListener) {
this.mHandleDataChangedListener = handleDataChangedListener;
}
public interface HandleDataChangedListener{
void onChanged();
}
In activity:
mListView.setHandleDataChangedListener(new CustomListView.HandleDataChangedListener() {
@Override
public void onChanged() {
mListView.setHandleDataChangedListener(null);
mListView.setSelection(0);
}
});
mAdapter.notifyDataSetChanged();
Ok, That's it.
Solution 11 - Android
In my case smoothScrollToPosition(int position) worked, can you also tell me how to set that scrolled position into center of the list. It appeared at the bottom of visible items.
Solution 12 - Android
For me it helped to set
ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
or ListView.CHOICE_MODE_MULTIPLE
then
ListView.setSelection(position)
or ListView.setItemChecked(position, true);
works fine
Solution 13 - Android
Found a solution in my case. I am not using a Runnable since my class is extending ListFragment. What I had to do is make my index a final; final index = 5; mListView.setSelection(index);
Solution 14 - Android
I found that sometimes setSelection will not work because I set attribute "android:height" of listView to "wrap_content".
And the times my App won't work is that when listView become scrollable from non-scrollable.
For example, if my app is "File Browser App". When my list is less than, let's say 6, then it's non-scrollable. Now I return to the parent directory, and it has 11 objects, and I want to set selection to some position, and it won't work here.
to\from | Scrollable | non-Scrollable
Scrollable | O | O( of course )
non-Scrollable | X | O( of course )
I don't want to use post(Runnable), because there will has delay.
==================================
Answer:
You can try to set "android:height" to "match_parent"
God, it spends three days.
Solution 15 - Android
When use post to setSelection()
, the ListView
will see first , then scroll to the position , thank to "魏經軒", then layout actually will effect the setSelection()
, because setSelection()
call the setSelectionFromTop(int position, int y)
, there is another way to solve it.
listView.setAdapter(listView.getAdapter());
listView.setSelection(123);
Solution 16 - Android
Simply try this code
listView.setAdapter(adapter);
listView.setSelection(position);
adapter.notifyDataSetChanged();
Solution 17 - Android
For me the solution to this problem was:
listView.clearChoices();