setSelection не меняет положение ListView - PullRequest
13 голосов
/ 11 августа 2011

У меня возникли проблемы с методом ListView setSelection.Я пытаюсь, чтобы мой список оставался с тем же индексом при переключении между альбомной и портретной ориентацией.Однако каждый раз, когда я вращаюсь и действие воссоздается, просмотр списка начинается сверху.Я использую следующий код:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = new ArrayList<Integer>();
    for (Integer i : f_checkedMessages) {
        indices.add(i);
    }
    savedInstanceState.putIntegerArrayList("CheckedMessageIndices", indices);
    savedInstanceState.putInt("ListIndex", f_listView.getFirstVisiblePosition());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = savedInstanceState.getIntegerArrayList("CheckedMessageIndices");
    for (Integer i : indices) {
        f_checkedMessages.add(i);
    }
    int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.setSelection(listIndex);
}

Я использовал отладчик для проверки правильности значения listIndex.Следует также отметить, что проверенные элементы списка сохраняются при изменении ориентации.Я знаю, что setSelected только ВЫБИРАЕТ элемент просмотра списка, если в сенсорном режиме, но документация говорит, что этот метод выравнивает просмотр списка независимо от того, в сенсорном режиме или нет.есть лучший способ сделать это?

Спасибо, ваша помощь очень ценится!

Ответы [ 9 ]

33 голосов
/ 18 января 2013

Если после нескольких часов, потерянных с этой проблемой, мне поможет дальнейшая помощь, я смог решить ее, используя тот же пример A-IV, с некоторыми изменениями.

Прежде всего, важно, чтобы методclearFocus () вызывается перед выполнением runnable.

Устройства, которые имеют такой же контроллер сенсорного режима, не имеют визуального эффекта при вызове метода setSelection (index), но элемент обычно выбирается.Поэтому необходимо вызвать requestFocusFromTouch (), чтобы включить визуальные изменения, вызванные методом setSelection (index).

После вызова setSelection (index), вызвать requestFocus (), чтобы дать фокус на просмотр.

@Override public void onRestoreInstanceState(Bundle savedInstanceState) {
...
final int listIndex = savedInstanceState.getInt("ListIndex");
f_listView.clearFocus();
f_listView.post(new Runnable() {
    @Override
    public void run() {
        listView.requestFocusFromTouch();
        listView.setSelection(listIndex);
        listView.requestFocus();
    }
});

}

Надеюсь, я помог!

9 голосов
/ 19 мая 2014

Вы можете использовать следующий код для решения этой проблемы

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    listView = getListView();
    listView.setAdapter(adapter);

    listView.post(new Runnable()
    {
        public void run()
        {
            listView.setSelection(position);
        }
    });
} 

ИЛИ

listView.setAdapter(adapter);
listView.setSelection(position);
adapter.notifyDataSetChanged(); 

ИЛИ Пожалуйста, перейдите по следующей ссылке:

http://www.codeproject.com/Tips/514527/ListActivity-setSelection-within-onCreate

Я надеюсь, что вы получите решение.Спасибо

7 голосов
/ 24 мая 2012

Вы не можете установить выбор сразу после изменения данных. Попробуйте это:

@Override public void onRestoreInstanceState(Bundle savedInstanceState) {
    ...
    final int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.post(new Runnable() {
        @Override
        public void run() {
            listView.setSelection(listIndex);
        }
    });
}
3 голосов
/ 28 августа 2012

Возможно, вам следует использовать «smoothScrollToPosition (int position)», если вы находитесь на уровне SDK> = 8.

1 голос
/ 09 апреля 2016

Проблема для меня заключалась в том, что я звоню adapter.notifyDataSetChanged (); после звонка mListView.setSelection (0);

Теперь я звоню в следующем порядке:

 adapter.notifyDataSetChanged();
 mListView.setSelection(0);

и все работает.

0 голосов
/ 05 марта 2018

используйте этот код,

sp2.setAdapter(sp2.getAdapter());
        sp2.getAdapter().notifyDataSetChanged();
        sp2.setSelection(0, false);
0 голосов
/ 16 июня 2016

Я думаю, что нашел лучшее решение, не используя сообщение Runnable:

list.setAdapter(adapter);
list.setSelection(list.getCount() - 1);
0 голосов
/ 13 января 2016

Единственное решение, которое сработало для меня, было:

    mListView.postDelayed(new Runnable() {
        @Override
        public void run() {
            mListView.setSelection(index);
        }
    }, 300);

Выглядит ужасно, но при этом работает как в сенсорном, так и в не сенсорном режимах.

0 голосов
/ 22 апреля 2013

Если ваш ListView внутри ListFragment, просто вызовите setSelection () .

...