Reputation: 5511
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?
Upvotes: 67
Views: 88851
Reputation: 331
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.
Upvotes: 2
Reputation: 643
Simply try this code
listView.setAdapter(adapter);
listView.setSelection(position);
adapter.notifyDataSetChanged();
Upvotes: -1
Reputation: 135
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 ;)
Upvotes: 4
Reputation: 1
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);
Upvotes: 0
Reputation: 17
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.
Upvotes: 0
Reputation: 57
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.
Upvotes: 4
Reputation: 91
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);
Upvotes: 0
Reputation: 505
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);
}
});
Upvotes: 39
Reputation: 7703
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
Upvotes: 0
Reputation: 61
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.
Upvotes: 0
Reputation: 1690
Maybe you should use the smoothScrollToPosition(int position) method of ListView
Upvotes: 2
Reputation: 23000
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);
Upvotes: 7
Reputation: 3921
maybe you need to use function:
ListView.setItemChecked(int position, boolean checked);
Upvotes: 107
Reputation: 6340
You might need to wrap setSelection()
in a post
ed Runnable
(reference).
Upvotes: 17
Reputation: 1006539
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...
Upvotes: 13