Android: установить элемент как выбранный при открытии ListView? - PullRequest
15 голосов
/ 08 октября 2010

У действия есть Button и ListView.Изначально видна только кнопка.Когда кнопка нажата, отображается ListView.Можно ли при отображении отобразить один конкретный элемент как выбранный / сфокусированный?

Может быть случай использования, предполагающий, что это список языковых настроек, и когда этот список открывается, текущий выбранный язык должен бытьотображается как выделенный.

Если я знаю индекс элемента, как установить его как фокусируемый на дисплее?

Ответы [ 4 ]

40 голосов
/ 18 июня 2013

Я публикую свое решение, потому что Google до сих пор не знает ответа.

getListView().setItemChecked(selectedGroupIndex, true);
15 голосов
/ 08 октября 2010

Короче говоря, ListView :: setSelection (int position) - это то, что вам нужно.Однако, в зависимости от того, находится устройство в сенсорном режиме или нет, оно может иметь или не иметь визуальный эффект (выделение фона).Для получения дополнительной информации см. Проблема выбора списка Android *

13 голосов
/ 23 апреля 2012

Если вы используете Adapter для вашего ListView, добавьте этот код в ваш адаптер:

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

В вашем Activity:

myAdapter.setSelectedItem(1);
0 голосов
/ 03 апреля 2016

Я использую адаптер и не хочу устанавливать собственные цвета фона, но использую android: state_selected в drawable xml. SetSelection не работает для меня, но, может быть, это также потому, что мне нужен SetNotifyDataChanged, который показывает, что выбранное состояние не является постоянным.

Я также обнаружил, что состояние Selected для элемента в ListView не является постоянным, поскольку SetNotifyDataChanged приводит к обновлению макета ListView, который очищает их все. Установка элемента на Selected в GetView адаптера тоже слишком рано.

В конце концов я установил состояние «Выбрано» для представления выбранного элемента после изменения макета списка, то есть, когда запускается событие LayoutChange (в Java это, вероятно, присоединение к OnLayoutChangeListener ListView).

Чтобы сделать это действительно легко, я сохраняю вид выбранного элемента как SelectedItemView Адаптера. В обработчике событий ListView LayoutChange я просто установил для SelectedItemView.Selected адаптера значение true.

Вот код из моей Деятельности, где я устанавливаю Адаптер для ListView, а также подписываюсь на LayoutChange (или в Java присоединяю 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;
        };

Вот мой код для адаптера:

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