Должны ли мы использовать RecyclerView для замены ListView?

232

Документы Android говорят:

Виджет RecyclerView - это более продвинутая и гибкая версия ListView. Этот виджет представляет собой контейнер для отображения больших наборов данных, которые можно очень эффективно прокручивать, поддерживая ограниченное количество просмотров. Используйте виджет RecyclerView, если у вас есть коллекции данных, элементы которых изменяются во время выполнения в зависимости от действий пользователя или сетевых событий

На самом деле ListViewможет сделать все вышеперечисленное, если эффективность не имеет значения, и мы нашли много проблем, когда мы используем RecyclerViewдля замены ListView:

  1. Для выбора элемента списка не существует onItemClickListener () - решение

  2. Нет делителя между элементами списка - решение

  3. Нет встроенного селектора перекрытия, нет визуальной обратной связи при нажатии на элемент списка - решение

  4. Нет addHeaderView для заголовка списка - решение

Может быть, больше вопросов ...

Поэтому, когда мы используем RecyclerViewдля замены ListView, мы должны сделать много дополнительного кодирования, чтобы достичь того же эффекта, что и ListView.

ВОПРОС:

  • Стоит ли мы заменить ListViewс RecyclerViewполностью?
  • если нет, то в каком случае лучше использовать RecyclerViewвместо этого ListView, и наоборот?
Xcihnegn
источник
9
ваша тема - это только первая проблема, и это не мой вопрос
Xcihnegn
3
Просто отметьте, что вы должны использовать переработчик, если вы заинтересованы в использовании свернутой панели действий. medium.com/android-bites/…
франкас
Вы должны использовать реселлер, потому что он предлагает больше контроля, чем список. Это немного сложно, но вы доберетесь, тогда ваша жизнь будет очень легкой, когда вы будете иметь дело со списком вещей.
Садашив
3
лучше враг добра.
старше

Ответы:

118

Если ListView работает для вас, нет причин для миграции. Если вы пишете новый пользовательский интерфейс, вам может быть лучше с RecyclerView.

RecyclerView эффективен, когда вам нужно настроить свой список или вы хотите более качественную анимацию. Эти удобные методы в ListView доставили много хлопот людям, поэтому RecyclerView предоставляет им более гибкое решение.

Основное изменение, которое вам нужно сделать для переноса, заключается в вашем адаптере. Если вы хотите продолжать звонить notifyDataSetChanged, вы теряете большинство преимуществ анимации и привязки. Но если вы можете изменить свой адаптер для отправки подробных событий уведомления (добавлено / удалено / перемещено / обновлено), то вы получите намного лучшую анимацию и производительность. Эти события позволяют RecyclerView выбрать правильную анимацию, а также помогают избежать ненужных onBindвызовов. Вы получите огромную выгоду, если ваши элементы сложны. Кроме того, в будущем вокруг RecyclerView будет больше компонентов.

Yigit
источник
2
Если бы я мог дать вам 100 голосов, я бы. Этот notifyDataSetChanged()метод заставлял меня RecyclerViewпостоянно просить новое ViewHolders, уничтожая все преимущества ViewHolderпаттерна. В поисках решения я нашел ваш комментарий, который довольно кстати попутно отвечает на мою проблему: D спасибо!
Стремящийся Dev
Я не согласен: «Вы получите огромную выгоду, если ваши представления элементов сложны», у меня есть recyclerView, в котором у адаптера есть 3, если еще, Recyclerview работает плохо в моем случае. Пришлось отключить утилизацию с помощью isRecyclable(false);и в итоге получился крайне лагированный RecyclerView. Я даже не могу изменить это, потребуется много времени, чтобы вернуться к просмотру списка :(
kashyap jimuliya
4
люди используют RV с гораздо большим количеством типов, чем без проблем и с хорошей производительностью. В вашем коде что-то не так. Вы должны использовать systrace / traceview и посмотреть, что происходит.
Yigit
1
@kashyapjimuliya, как упомянул Йигит , 3 если иное не должно быть причиной этого. Во-первых, вы не упомянули, куда кладете эти if-else; во-вторых, отключение утилизации должно замедлять, а не ускорять. Зачем? Потому что надувать взгляд и делать findViewById()это намного дороже, чем делать это так, как ViewHolderнадо.
Суфий
24

По моему мнению, если ListView удовлетворяет всем текущим потребностям вашего приложения и удовлетворяет всем сценариям использования, тогда нет необходимости заменять его RecyclerView.

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

Но да, существует много вещей, которые ListView никогда не сможет сделать, например, удивительная функция LayoutManager, которая позволяет динамически изменять макет на горизонтальную, вертикальную, сеточную или смещенную сетку.

Я написал подробный ответ на эту тему здесь .

Аритра Рой
источник
3
Конечно, RecyclerView увеличивает сложность, но, по крайней мере, он правильно реализует шаблон ViewHolder.
Игорь Ганапольский
@IgorGanapolsky +1 для реализации шаблона ViewHolder.
Sreekanth Karumanaghat
Вы можете написать свой собственный шаблон держателя вида просто отлично с ListView
Дан
9

1 Вы можете использовать интерфейс для прослушивания щелчков. Я использую эту технику с ListViews тоже.
2 Без делителя: просто добавьте в вашу строку View с шириной match_parent и высотой 1dp и присвойте ему цвет фона .
3 Просто используйте селектор StateList для фона строки.
4 addHeaderView можно также избежать в ListViews: просто поместите заголовок за пределы представления.

Так что, если вы заинтересованы в эффективности, тогда да , это хорошая идея заменить ListView на RecyclerView.

Phantômaxx
источник
19
Это не мои вопросы, у меня была ссылка для каждого решения проблемы
Xcihnegn
6

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

Я основал это решение на «человеческих факторах», что создание простого ListView с меньшим количеством кода лучше, если производительность не имеет значения. Я часто вспоминаю профессора в колледже, который любил говорить: «Мой учитель, великий Никлаус Вирт, изобретатель Паскаля, говорил, что если в программе более 50 строк кода, то это наверняка будет неправильно ...»

Но что убедило меня прекратить использование ListView, так это то, что он недавно был перемещен в категорию «Legacy» в инструменте дизайна Android Studio вместе с RelativeLayout.

https://developer.android.com/reference/android/widget/ListView

Я думаю, что это «мягкая» форма «обесценивания». Это было бы слишком разрушительным, если бы это было фактически устарело, и все добросовестные разработчики перенесли свой код в RecyclerView.

Кроме того, введение в ListView прямо вверху предупреждает, что RecyclerView является лучшим вариантом: «Для более современного, гибкого и производительного подхода к отображению списков используйте RecyclerView».
https://developer.android.com/reference/android/widget/ListView

Кроме того, в руководстве по ListView по-прежнему говорится о загрузчиках курсора, но затем сам API getSupportCursorLoader () был объявлен устаревшим в API 28.
https://developer.android.com/guide/topics/ui/layout/listview

Последние улучшения в Android Studio:

Файл -> Создать -> Фрагмент -> Фрагмент (список)

Это дает нам полностью рабочий RecylerView, заполненный основным текстом. Это избавляет меня от моей последней реальной причины использования ListView, поскольку теперь так же легко настроить базовый RecylerView.

Таким образом, я не собираюсь использовать ListView вообще для новой разработки, потому что маркировка его «наследие» находится в одном шаге от его устаревшего.

Elletlar
источник
3

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

Для любого другого использования RecyclerView затмевает ListView. Поскольку RecyclerView заботится только об утилизации, будет проще создавать визуально связанные вещи, которые были тесно связаны в ListView, такие как изменение положения / перестановка, анимация (на самом деле это происходит с RecyclerView.ItemAnimator), пользовательские макеты (в запасе есть StaggeredGrid в дополнение к старый список или стиль сетки, но есть и эта библиотека, которая расширяет его еще больше).

Кроме того, если вы хотите использовать CardView, я считаю, что это единственный путь ( хорошее чтение, когда использовать карту или список).

inmyth
источник
Вы имеете в виду захват списка данных с серверов, а затем сохранение их в sqlite на телефоне, который будет использоваться для отображения списка (скажем, ваших подписчиков), лучше использовать представление рециркулятора, чем представление списка с держателем представления ?
Lion789
Да. Но, если быть точным, я больше не вижу никакой роли для ListView, кроме навигации, и это потому, что я думаю, что использовать RecyclerView там излишне.
Inmyth
2

Отличная альтернатива - использование BaseAdapter. Он поддерживает использование шаблона Viewholder, а мой содержит более 100 строк с растровыми изображениями и кнопками и работает очень плавно.

grantespo
источник