Android:To set an item as selected when the ListView opens?
Asked Answered
C

4

15

An activity has a Button and a ListView. Initially, only the Button is visible. When the button is pressed, the ListView is displayed. When displayed, is it possible for me to show one particular item as selected/focussed?

A use case could be that suppose it is a list of language settings and when the list opens, the currently selected language must be shown as highlighted.

If I know the index of the item, how to set it as focused on display?

Cathrine answered 8/10, 2010 at 5:49 Comment(0)
T
15

In short, ListView::setSelection(int position) is what you need. However, depending on whether the device is in touch mode or not, it may or may not have visual effect (background highlighting). For more details, refer to Android ListView Selection Problem

Thanet answered 8/10, 2010 at 7:12 Comment(6)
Nope, setSelection(pos) does not solve my problem! The device is not in touch mode, but still i do not get the backgound highlighting. I am simply testing on an emulator. My list view is using a selector xml, hope that has no effect on this!Cathrine
How do you know your device is not in touch mode? Maybe you can try to use the navigation key to highlight the button and use the center key to press the button. See if that makes a difference.Thanet
I am simply working with the emulator now in Eclipse. And using my PC's keyboard to work with.Cathrine
How did you press the button? Did you use mouse or only keyboard?Thanet
Try adding the two lines: listView.setFocusable(true); listview.setFocusableInTouchMode(true);Thanet
Well, I accept this answer. But felt a more presentable solution is to use a CheckedTextViw as my list items. And the default selected item is shown as checked. More easy to understand!Cathrine
D
41

I post my solution, because google still doesn't know the answer.

getListView().setItemChecked(selectedGroupIndex, true);
Disparate answered 18/6, 2013 at 14:42 Comment(3)
vote +1 to accept this post as an answer, instead of setSelectionBhayani
This doesn't work for me, could you elaborate please ? Is this still relevant in 2018 ?Autoclave
@DanChaltiel I just tested it, it works in a way (S9, Android 8.0). From what I've seen myListView.setItemChecked(-1,true); still sets the pointer to "-1" and that's also the value myListView.getCheckedItemPosition(); will return but unfortunately it doesn't seem to mark the actual item as selected (= give it the other background color). Not sure what to do for that but what I can tell you is that you have to use the "checked" methods if you're using a touchscreen device because the others like getSelectedItemPosition and setSelection don't work properly then.Animation
T
15

In short, ListView::setSelection(int position) is what you need. However, depending on whether the device is in touch mode or not, it may or may not have visual effect (background highlighting). For more details, refer to Android ListView Selection Problem

Thanet answered 8/10, 2010 at 7:12 Comment(6)
Nope, setSelection(pos) does not solve my problem! The device is not in touch mode, but still i do not get the backgound highlighting. I am simply testing on an emulator. My list view is using a selector xml, hope that has no effect on this!Cathrine
How do you know your device is not in touch mode? Maybe you can try to use the navigation key to highlight the button and use the center key to press the button. See if that makes a difference.Thanet
I am simply working with the emulator now in Eclipse. And using my PC's keyboard to work with.Cathrine
How did you press the button? Did you use mouse or only keyboard?Thanet
Try adding the two lines: listView.setFocusable(true); listview.setFocusableInTouchMode(true);Thanet
Well, I accept this answer. But felt a more presentable solution is to use a CheckedTextViw as my list items. And the default selected item is shown as checked. More easy to understand!Cathrine
S
13

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);
Selle answered 23/4, 2012 at 8:45 Comment(0)
B
0

I am using an Adapter and didn't want to set custom background colors, but use the android:state_selected in drawable xml. SetSelection didn't work for me, but maybe that's also since I needed SetNotifyDataChanged which shows that the Selected State is not persistent.

I also found that the Selected state for an item in a ListView is not persistent, since SetNotifyDataChanged results in updating the ListView layout which clears them all. Setting the item to Selected in the Adapter's GetView is too soon too.

Eventually I set the Selected state for the view of the selected item after the layout of the listview has been changed, which is when LayoutChange event is being triggered (in Java it's probably attaching a to OnLayoutChangeListener of the ListView).

To make it really easy I store the view of the selected item as Adapter's SelectedItemView. In the ListView's LayoutChange eventhandler I just set the adapter's SelectedItemView.Selected to true.

Here's the code from my Activity where I set the Adapter for the ListView and also subscribe to LayoutChange (or in Java attach an OnLayoutChangeListener)

        ringTonesListView.Adapter = ringTonesListAdapter;
        ringTonesListView.LayoutChange += (s, layoutChangeArgs) => {
            //At this stage the layout has been updated and the Selected can be set to true for the view of the selected item. This will result in android:state_selected logic to be applied as desired and styling can be completely done per layout in Resources.
            ringTonesListAdapter.SelectedItemView.Selected = true;
        };

Here's my code for the Adapter:

public class RingTonesListAdapter : BaseAdapter<RingToneItem>
{
    List<RingTone> Items { get; set; }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View view = convertView;

        // re-use an existing view, if one is available
        // otherwise create a new one
        if (view == null)
        {
            view = Context.LayoutInflater.Inflate(Resource.Layout.AlertSoundItem, parent, false);
            view.Click += SelectRingTone;
        }

        RingTone ringTone = this[position];
        if (ringTone.Selected)
        {
            //==> Important
            //Store this view since it's the view for the Selected Item
            SelectedItemView = view;
            //Setting view.Selected to true here doesn't help either, since Selected will be cleared after.
        }

        return view;
    }

    private void SelectRingTone(object sender, EventArgs args)
    {
        View view = (View)sender;
        string title = view.FindViewById<TextView>(Resource.Id.ringToneTitle).Text;
        RingToneItem ringToneItem = Items.First(rt => rt.Title == title);
        if (!ringToneItem.Selected)
        {
            //The RingTone was not selected and is selected now
            //Deselect Old and Select new
            foreach (RingToneItem oldItem in Items.Where(rt => rt.Selected))
            {
                oldItem.Selected = false;
            }

            // Select New RingTone
            ringToneItem.Selected = true;
            //Update the ListView. 
            //This will result in removal of Selected state for all Items when the ListView updates it's layout
            NotifyDataSetChanged();
        }

        //Now play the test sound
        NotifierService.TestSound(Context, ringToneItem);
    }

    public View SelectedItemView { get; set; }
}
Bargeboard answered 2/4, 2016 at 21:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.