Android ListView setSelection () не работает - PullRequest
65 голосов
/ 18 сентября 2009

У меня есть ListActivity, который реализует onListItemClick() и вызывает функцию doSomething() класса. Последний содержит l.setSelection(position), где l - объект ListView.

Теперь onClickListener() слушает нажатие кнопки, которое выполняет некоторые действия и тоже вызывает doSomething().

В первом случае выбранный элемент позиционируется соответствующим образом, но во втором случае ничего не происходит.

Есть какие-нибудь подсказки об этом странном поведении и о том, как я могу заставить его работать?

Ответы [ 17 ]

103 голосов
/ 19 января 2011

может быть, вам нужно использовать функцию:

ListView.setItemChecked(int position, boolean checked);
65 голосов
/ 24 августа 2010

используйте requestFocusFromTouch() перед вызовом setSelection() метода

31 голосов
/ 20 марта 2014

Я знаю, что это старый вопрос, но у меня была похожая проблема, которую я решил следующим образом:

mListView.clearFocus();
mListView.post(new Runnable() {
    @Override
    public void run() {
        mListView.setSelection(index);
    }
});
15 голосов
/ 04 мая 2010

Возможно, вам понадобится обернуть setSelection() в post ed Runnable ( ссылка ).

13 голосов
/ 19 сентября 2009

setSelection() не обязательно оказывает визуальное воздействие. Панель выбора появляется только в том случае, если вы используете D-pad / трекбол для навигации по списку. Если вы нажмете на экран, чтобы что-то щелкнуть, строка выбора появится на короткое время и исчезнет.

Следовательно, setSelection() будет иметь визуальный эффект только в том случае, если действие не в сенсорном режиме (т.е. последнее, что пользователь сделал, - это использование D-pad / trackball).

Я не уверен на 100%, что это объясняет ваше явление, учитывая описание, которое вы предоставили, но я решил, что это стоит попробовать ...

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

Если вы используете адаптер для вашего 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;
    }

}

В вашей деятельности:

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

У меня очень большой запрос с веб-контентом. Когда я использовал код в onCreateView, Listview даже не закончил загрузку. Я поместил его в PostExecute моей 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);
                }
            });
        }

Не забудьте установить отмеченный пункт при клике;)

3 голосов
/ 22 сентября 2014

Для меня звонит

listView.notifyDataSetChanged();
listView.requestFocusFromTouch();

, а затем

 listView.setSelection(position);

решил проблему.

если вы сделаете это в исполняемом модуле, он будет работать без вызова requestFocusFromTouch (), но старая позиция ListView будет показана для sekound.

2 голосов
/ 28 августа 2012

Возможно, вам следует использовать метод smoothScrollToPosition (int position) ListView

0 голосов
/ 30 июля 2018

Вы можете попробовать 2 способа, подобные этим:
Решение А:

    mListView.post(new Runnable() {
        @Override
        public void run() {
            if (null != mListView) {
                mListView.clearFocus();
                mListView.requestFocusFromTouch();
                mListView.setSelection(0);
            }
        }
    });

В некоторых сложных ситуациях это решение принесет некоторые новые проблемы в Android 8.x.
Кроме того, оно может вызвать неожиданное onFocusChange ().

Решение B: Определить пользовательский вид расширяет ListView. Переопределите метод handleDataChanged (). Затем setSelection (0). В 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();
}

В деятельности:

    mListView.setHandleDataChangedListener(new CustomListView.HandleDataChangedListener() {
        @Override
        public void onChanged() {
            mListView.setHandleDataChangedListener(null);
            mListView.setSelection(0);
        }
    });
    mAdapter.notifyDataSetChanged();

Хорошо, вот и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...