开发者

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

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?


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

getListView().setItemChecked(selectedGroupIndex, true);


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


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


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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜