Я долго, ListView
что пользователь может прокручивать перед возвратом к предыдущему экрану. Когда пользователь откроет это ListView
снова, я хочу, чтобы список был прокручен до той же точки, что и ранее. Есть идеи как этого добиться?
android
android-listview
scroll
scroll-position
rantravee
источник
источник
Ответы:
Попробуй это:
Объяснение:
ListView.getFirstVisiblePosition()
возвращает наиболее видимый элемент списка. Но этот элемент может быть частично прокручен вне поля зрения, и если вы хотите восстановить точную позицию прокрутки списка, вам нужно получить это смещение. ПоэтомуListView.getChildAt(0)
возвращаетView
для верхнего элемента списка, а затемView.getTop() - mList.getPaddingTop()
возвращает его относительное смещение от верхней частиListView
. Затем, чтобы восстановитьListView
позицию прокрутки, мы вызываемListView.setSelectionFromTop()
индекс нужного элемента и смещение, чтобы расположить его верхний край от вершиныListView
.источник
int index = mList.getFirstVisiblePosition();
и только одна линия для восстановления:mList.setSelectionFromTop(index, 0);
. Отличный ответ (+1)! Я искал элегантное решение этой проблемы.источник
Я принял решение, предложенное @ (Кирк Волл), и оно работает для меня. Я также видел в исходном коде Android для приложения «Контакты», что они используют похожую технику. Я хотел бы добавить еще несколько деталей: в верхней части моего класса, производного от ListActivity:
Затем некоторые методы переопределяют:
Конечно, «loadData» - это моя функция для извлечения данных из БД и помещения их в список.
На моем устройстве Froyo это работает как при изменении ориентации телефона, так и при редактировании элемента и возвращении к списку.
источник
mListState = getListView().onSaveInstanceState().
основном при ротации устройства.onRestoreInstanceState
никогда не называется :(Очень простой способ:
Метод setSelection сбрасывает список до предоставленного элемента. Если не в сенсорном режиме, элемент будет фактически выбран, если в сенсорном режиме он будет размещен только на экране.
Более сложный подход:
источник
Я нашел что-то интересное по этому поводу.
Я попробовал setSelection и scrolltoXY, но он не работал вообще, список остался в том же положении, после некоторых проб и ошибок я получил следующий код, который работает
Если вместо публикации Runnable вы пытаетесь запустить runOnUiThread, он также не работает (по крайней мере, на некоторых устройствах)
Это очень странный обходной путь для чего-то, что должно быть прямым.
источник
setSelectionFromTop()
не работает.ВНИМАНИЕ !! В AbsListView есть ошибка, которая не позволяет onSaveState () работать правильно, если ListView.getFirstVisiblePosition () равен 0.
Так что если у вас есть большие изображения, которые занимают большую часть экрана, и вы прокручиваете до второго изображения, но показывает немного первого, положение прокрутки не будет сохранено ...
от AbsListView.java:1650 (комментарии мои)
Но в этой ситуации «верх» в приведенном ниже коде будет отрицательным числом, что вызывает другие проблемы, препятствующие правильному восстановлению состояния. Таким образом, когда «верх» отрицательный, получить следующий ребенок
источник
Достаточно
источник
Для тех, кто ищет решение этой проблемы, корень проблемы может быть в том, где вы настраиваете свой адаптер представления списка. После того, как вы установите адаптер в списке, он сбрасывает позицию прокрутки. Просто кое-что рассмотреть. Я переместил установку адаптера в свой onCreateView после того, как мы получили ссылку на просмотр списка, и это решило проблему для меня. знак равно
источник
Отправляю это, потому что я удивлен, что никто не упомянул это.
После того, как пользователь нажмет кнопку «Назад», он вернется к списку в том же состоянии, в котором он вышел из него.
Этот код переопределяет кнопку «вверх», чтобы вести себя так же, как кнопка «назад», поэтому в случае Listview -> Details -> Back to Listview (и без других опций) это самый простой код для поддержки положения прокрутки и содержимого. в списке.
Предостережение: если вы можете перейти к другому действию из подробного действия, кнопка вверх вернет вас к этому действию, поэтому вам придется манипулировать историей кнопок, чтобы это работало.
источник
Разве недостаточно просто
android:saveEnabled="true"
в объявлении ListView xml?источник
ЛУЧШЕЕ РЕШЕНИЕ:
ВЫ ДОЛЖНЫ ЗВОНИТЬ В ПОЧТУ И В РЕЗЬБЕ!
источник
Вы можете сохранить состояние прокрутки после перезагрузки, если сохраните состояние до перезагрузки и восстановите его после. В моем случае я сделал асинхронный сетевой запрос и перезагрузил список в обратном вызове после его завершения. Здесь я восстанавливаю состояние. Пример кода - Котлин.
источник
Если вы используете фрагменты, размещенные в действии, вы можете сделать что-то вроде этого:
источник
Если вы сохраняете / восстанавливаете свою позицию прокрутки,
ListView
вы по сути дублируете функциональность, уже реализованную в платформе Android. Сама по себеListView
точная позиция прокрутки восстанавливается сама по себе, за исключением одного предупреждения: как упомянул @aaronvargas, есть ошибкаAbsListView
, которая не позволяет восстановить позицию точной прокрутки для первого элемента списка. Тем не менее, лучший способ восстановить положение прокрутки - не восстанавливать его. Android Framework сделает это лучше для вас. Просто убедитесь, что вы выполнили следующие условия:setSaveEnabled(false)
метод и не задалиandroid:saveEnabled="false"
атрибут для списка в файле макета xmlExpandableListView
переопределения,long getCombinedChildId(long groupId, long childId)
чтобы он возвращал положительное длинное число (реализация по умолчанию в классеBaseExpandableListAdapter
возвращает отрицательное число). Вот примеры:,
ListView
илиExpandableListView
используется во фрагменте, не воссоздайте фрагмент при восстановлении активности (например, после поворота экрана). Получить фрагментfindFragmentByTag(String tag)
методом.ListView
есть,android:id
и это уникально.Чтобы избежать вышеупомянутого предостережения с первым элементом списка, вы можете создать свой адаптер так, как он возвращает специальный фиктивный вид нулевой высоты пикселей для
ListView
позиции 0. Здесь приведен простой пример проекта, который показываетListView
иExpandableListView
восстанавливает свои точные позиции прокрутки, тогда как их позиции прокрутки явно не сохраняются. / восстановления. Точная позиция прокрутки восстанавливается идеально даже для сложных сценариев с временным переключением на какое-либо другое приложение, двойным поворотом экрана и переключением обратно на тестовое приложение. Обратите внимание, что если вы явно выходите из приложения (нажав кнопку «Назад»), позиция прокрутки не будет сохранена (равно как и все другие виды не сохранят свое состояние). https://github.com/voromto/RestoreScrollPosition/releasesисточник
Для действия, производного от ListActivity, который реализует LoaderManager.LoaderCallbacks с использованием SimpleCursorAdapter, не удалось восстановить позицию в onReset (), поскольку действие почти всегда перезапускалось, и адаптер перезагружался при закрытии представления сведений. Хитрость заключалась в том, чтобы восстановить позицию в onLoadFinished ():
в onListItemClick ():
в onLoadFinished ():
в onBackPressed ():
источник
Похоже, ни одно из предложенных здесь решений не сработало для меня. В моем случае у меня есть переменная
ListView
в,Fragment
которую я заменяю вFragmentTransaction
, поэтомуFragment
каждый раз, когда показывается фрагмент , создается новый экземпляр, что означает, чтоListView
состояние не может быть сохранено в качестве членаFragment
.Вместо этого я закончил хранить состояние в своем пользовательском
Application
классе. Код ниже должен дать вам представление о том, как это работает:Основная идея заключается в том, что вы сохраняете состояние вне экземпляра фрагмента. Если вам не нравится идея иметь статическое поле в классе приложения, я думаю, вы могли бы сделать это, реализовав фрагментный интерфейс и сохранив состояние в вашей активности.
Другим решением было бы сохранить его
SharedPreferences
, но это немного сложнее, и вам нужно будет обязательно очистить его при запуске приложения, если только вы не хотите, чтобы состояние сохранялось при запуске приложения.Кроме того, чтобы избежать «позиции прокрутки, которая не сохраняется, когда виден первый элемент», вы можете отобразить фиктивный первый элемент с
0px
высотой. Это может быть достигнуто путем переопределенияgetView()
в вашем адаптере, например:источник
Мой ответ для Firebase, а позиция 0 - это обходной путь
и convertView
позиция 0 добавить пустой элемент, который вы не используете
Я видел эту работу временно, не мешая пользователю, я надеюсь, что она работает для вас
источник
используйте этот код ниже:
и всякий раз, когда вы обновляете свои данные, используйте следующий код:
источник
Я использую FirebaseListAdapter и не смог заставить работать ни одно из решений. Я закончил тем, что делал это. Я предполагаю, что есть более элегантные способы, но это полное и рабочее решение.
Перед созданием:
Внутри FirebaseListAdapter:
OnStart:
OnStop:
Так как я также должен был решить эту проблему для FirebaseRecyclerAdapter, я также выкладываю здесь решение для этого:
Перед созданием:
Внутри FirebaseRecyclerAdapter:
OnStart:
OnStop:
источник
Чтобы уточнить отличный ответ Райана Ньюсома и настроить его для фрагментов и для обычного случая, когда мы хотим перейти от «основного» фрагмента ListView к «подробному» фрагменту и затем вернуться к «главному»
Волшебство здесь в том, что когда мы возвращаемся от фрагмента подробностей к фрагменту ListView, представление не воссоздается, мы не устанавливаем адаптер ListView, поэтому все остается, как мы его оставили!
источник