Подтвердить что ты не робот

SetSelection не меняет позицию ListView

У меня возникают проблемы с методом 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 выбирает только элемент listview в режиме touch, но в документации говорится, что этот метод выравнивает список, независимо от того, находится ли он в режиме касания или нет.

Кто-нибудь знает, почему это не работает, или если есть лучший способ сделать это?

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

4b9b3361

Ответ 1

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

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

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

После вызова 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();
    }
});

}

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

Ответ 2

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

@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

Надеюсь, вы получите решение. Благодарю вас.

Ответ 3

Вы не можете установить выбор сразу после того, как данные были изменены. Попробуйте следующее:

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

Ответ 4

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

Ответ 5

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

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

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

и он работает.

Ответ 6

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

Ответ 7

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

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

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

Ответ 8

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

list.setAdapter(adapter);
list.setSelection(list.getCount() - 1);