Android Recyclerview проти ListView з Viewholder


148

Нещодавно я натрапив на андроїд, RecyclerViewякий був випущений з Android 5.0, і, здається, RecyclerViewце просто інкапсульований традиційний ListViewз вбудованим в нього візерунком ViewHolder, який сприяє повторному використанню подання, а не створенню його кожного разу.

Які ще є переваги використання RecyclerView? Якщо обидва мають однаковий ефект з точки зору продуктивності, чому б він віддав перевагу RecyclerView`?

Редагувати

Я виявив, що люди задавали подібне питання, і відповіді не є переконливими, додавши їх сюди для ведення обліку.

Recyclerview проти Listview

Чи слід використовувати RecyclerView для заміни ListView?

Чому RecyclerView не має OnItemClickListener ()? і чим RecyclerView відрізняється від Listview?


4
Тому що RecyclerViewнабагато швидше і універсальніше з набагато кращим API. Такі речі, як анімація додавання або вилучення елементів, вже реалізовані в тому, що RecyclerViewвам нічого не потрібно робити. Про це не йдеться, киньте його ListViewв сміттєвий контейнер, RecyclerViewє тут, щоб вкрасти шоу.
Xaver Kapeller

4
Ви можете пов’язати менеджер макетів з RecyclerView, щоб вони не обмежувались вертикально прокручуваними списками. Це досить потужний додатковий функціонал.
Алан

@Alan - Що ви маєте на увазі під "не обмежуючись вертикально прокручуваними списками"? Ви хочете сказати, що перегляд Recycle може також виконувати роль "заповнювача" для Gridviews та ListViews?
Mushtaq Jameel

@XaverKapeller - Було б чудово, якби ви могли перелічити відмінності між двома і відповісти на питання, а не на коментар, щоб це могло допомогти мені та іншим у майбутньому, хто, можливо, цікавиться одним і тим же?
Mushtaq Jameel

@Alan - Не могли б ви детальніше розповісти, що ви мали на увазі, і відповісти на питання, а не на коментар. Дякуємо, що
знайшли

Відповіді:


289

З появою Android Lollipop RecyclerView пробився офіційно. RecyclerView набагато потужніший, гнучкіший і значно покращує ListView . Я спробую дати вам детальну інформацію про це.

1) Шаблон ViewHolder

У ListView рекомендували використовувати шаблон ViewHolder, але це ніколи не було примусом. У разі RecyclerView це обов'язково за допомогою класу RecyclerView.ViewHolder . Це одна з головних відмінностей між ListView та RecyclerView.

Це робить речі трохи складнішими в RecyclerView, але багато проблем, з якими ми стикалися в ListView, вирішуються ефективно.

2) LayoutManager

Це ще одне масове вдосконалення, внесене до RecyclerView. У ListView єдиний тип перегляду доступний - вертикальний ListView. Офіційного способу навіть застосувати горизонтальний ListView немає.

Тепер, використовуючи RecyclerView, ми можемо мати

i) LinearLayoutManager - який підтримує як вертикальний, так і горизонтальний списки,

ii) StaggeredLayoutManager - який підтримує Pinterest як поетапні списки,

iii) GridLayoutManager - підтримує відображення сіток, як це бачиться в додатках Галереї.

І найкраще, що ми можемо робити все це динамічно, як хочемо.

3) Аніматор предмета

ListView не вистачає на підтримку хорошої анімації, але RecyclerView приносить їй зовсім новий вимір. Використовуючи клас RecyclerView.ItemAnimator , анімація поглядів стає настільки простою та інтуїтивно зрозумілою.

4) Прикраса предмета

У випадку ListView, динамічно декорувати елементи, такі як додавання меж або роздільників, ніколи не було просто. Але у випадку RecyclerView клас RecyclerView.ItemDecorator дає величезний контроль розробникам, але робить речі дещо більш трудомісткими та складними.

5) OnItemTouchListener

Перехоплення кліків елементів на ListView було простим, завдяки інтерфейсу AdapterView.OnItemClickListener . Але RecyclerView дає набагато більше влади та контролю своїм розробникам RecyclerView.OnItemTouchListener ( більше не підтримується, будь ласка, зверніться до AndroidX ), але це трохи ускладнює розробника.

Простими словами, RecyclerView набагато більш настроюється, ніж ListView, і дає багато контролю та влади своїм розробникам.


34
Хороша відповідь. Пара додаткових величезних плюсів: RecyclerView готує перегляд лише вперед та за видимими записами, що чудово, якщо ви отримуєте растрові карти у фоновому режимі. Продуктивність значно швидше, особливо якщо ви використовуєте RecyclerView.setHasFixedSize. Старий ListView базується на тому, що немає можливості перерахувати чи кешувати розмір записів у списку, що викликає шалені ускладнення під час прокрутки та виконання макета. Знадобиться певний час, щоб звикнути до цього, але як тільки ви це зробите, ви ніколи не повернетесь.
Робін Девіс

@RobinDavies Чудовий пункт. Дякуємо, що повідомили. Але це не матиме сенсу, якщо розміри предметів будуть різними.
Арітра Рой

@AritraRoy Recyclerview підтримує лише льодяник або api 14+ (android 4+) також? .... як я читав "після льодяника: у більшості місць
Animesh Mangla

2
Привіт, Арітра, якщо порівнювати з ListView, якщо ListView також використовує шаблон ViewHolder, який із них діє ефективніше? Чи перегляне Recyler краще, якщо використовує fps або інший подібний критерій? thx ~
RxRead

@RxRead: Дивіться коментар Робіна, він розрізняє RecyclerView Vs ListView від моделі власника перегляду за ознаками продуктивності.
Параг Кадам

10

Інший плюс використання RecycleView- це анімація, її можна зробити в двох рядках коду

RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
        recyclerView.setItemAnimator(itemAnimator);

Але віджет все ще залишається сирим, наприклад, ви не можете створити колонтитул і колонтитул .


5
І ви ніколи не зможете створити колонтитул в цьому сенсі. Вони просто інші типи перегляду у вашому адаптері. Перегляд списку завершує адаптер HeaderViewListAdapterі додає підтримку заголовка у фоновому режимі. З RecyclerViewтобою ти керуєш.
Євген Печанець

RecyclerView за замовчуванням використовує DefaultItemAnimator. Тоді для чого ви використовували цей код?
Атіра Редді

9

Добре так мало копати, і я знайшов ці дорогоцінні камені з статті Білла Філіпса наRecycleView

RecyclerView може зробити більше, ніж ListView, але сам клас RecyclerView має менше обов'язків, ніж ListView. RecyclerView не вказує:

  • Позиціонування елементів на екрані
  • Анімовані погляди
  • Обробляйте будь-які дотикові події, крім прокрутки

Весь цей матеріал був викладений у ListView, але RecyclerView використовує класи співпраці, щоб виконувати ці завдання замість цього.

Створені вами ViewHolders також є бідкателем. Вони підкласу RecyclerView.ViewHolder, який має купу методів RecyclerView використання. ViewHoldersзнайте, до якої позиції вони зараз прив’язані, а також до якого ідентифікатора елемента (якщо у вас є). У процесі ViewHolder цього був лицар. Це було завдання ListView, щоб утримувати перегляд усього елемента, іViewHolder він тримався лише за невеликі фрагменти.

Тепер ViewHolder тримається за все це в ViewHolder.itemView полі, яке призначено в конструкторі ViewHolder для вас.


4

Більше з статті Білла Філліпа (ідіть читайте!), Але я подумав, що важливо вказати на наступне.

У ListView виникла неоднозначність щодо обробки подій клацання. Чи повинні окремі представлення обробляти ці події, чи повинен ListView обробляти їх через OnItemClickListener? У RecyclerView, однак, ViewHolder перебуває у чіткому положенні, щоб діяти як об’єкт контролера рівня рядків, який обробляє такі види деталей.

Раніше ми бачили, що LayoutManager обробляє види позиціонування, а ItemAnimator обробляє їх анімацію. ViewHolder - це останній фрагмент: він відповідає за обробку будь-яких подій, що трапляються на певному елементі, який відображає RecyclerView.


2

Я використовував ListViewзавантажувач зображень Glide, маючи зростання пам’яті. Потім я замінив на ListViewa RecyclerView. Це не тільки складніше в кодуванні, але й призводить до більшого використання пам'яті, ніж ListView. Принаймні, в моєму проекті.

В іншій діяльності я використав складний список с EditText's. У деяких з них метод введення може відрізнятися, також TextWatcherможе бути застосовано a . Якщо я використовував a ViewHolder, як я можу замінити TextWatcherпід час прокрутки? Отже, я використовував a ListViewбез aViewHolder , і це працює.


Я використовував ListView без ViewHolder, і він працює. жахлива ідея ... як я міг замінити TextWatcher під час прокрутки? не потрібно його замінювати ... просто TextWacher після повторного використання повинен помістити дані в інший контейнер ... і це можна зробити дуже просто
Селвін

@Selvin, дякую за вашу думку. Зараз я не можу редагувати цей проект. На TextWatcherекрані було кілька с. Напевно, ви праві, але я не можу це перевірити.
CoolMind

1

Повторно використовує комірки під час прокрутки вгору / вниз - це можливо, застосувавши утримувач View View в адаптері listView, але це було необов'язково, тоді як у RecycleView це стандартний спосіб запису адаптера.

Розв'язує список від свого контейнера - так ви можете легко розміщувати елементи списку під час виконання роботи в різних контейнерах (linearLayout, gridLayout) з налаштуванням LayoutManager.

Приклад:

mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//or
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
  • Анімує спільні дії зі списку.

  • Анімації розв'язують та делегують ItemAnimator.

Про RecyclerView є більше, але я думаю, що ці моменти є основними.

LayoutManager

i) LinearLayoutManager - який підтримує як вертикальний, так і горизонтальний списки,

ii) StaggeredLayoutManager - який підтримує Pinterest як поетапні списки,

iii) GridLayoutManager - підтримує відображення сіток, як це бачиться в додатках Галереї.

І найкраще, що ми можемо робити все це динамічно, як хочемо.


1

1. Перегляд власників

У ListView запропонований спосіб визначення власників представлення даних пропонував підтримувати посилання на представлення даних. Але це не було примусом. Хоча, не роблячи цього, ListView використовував показ несвіжих даних. Інший головний недолік використання не власників представлень перегляду може спричинити важку операцію пошуку представлень ідентифікаторів кожного разу. Це призвело до млявих ListViews.

Ця проблема вирішується в RecylerView шляхом використання класу RecyclerView.ViewHolder. Це одна з головних відмінностей у RecyclerView та ListView. Під час реалізації RecyclerView цей клас використовується для визначення об'єкта ViewHolder, який використовується адаптером для зв'язування ViewHolder з позицією. Ще один момент, який слід зазначити, полягає в тому, що при впровадженні адаптера для RecyclerView надання ViewHolder є обов'язковим. Це робить реалізацію трохи складною, але вирішує проблеми, з якими стикається ListView.

2. Диспетчер макета

Якщо говорити про ListViews, доступний лише один тип ListView, тобто вертикальний ListView. Ви не можете реалізувати ListView з горизонтальною прокруткою. Я знаю, що існують способи реалізації горизонтальної прокрутки, але повірте, вона не була розроблена для роботи таким чином.

Але тепер, коли ми дивимось на Android RecyclerView проти ListView, у нас є підтримка і для горизонтальних колекцій. Насправді він підтримує декілька типів списків. Для підтримки декількох типів списків використовується клас RecyclerView.LayoutManager. Це щось нове, що у ListView немає. RecyclerView підтримує три типи попередньо визначених менеджерів макета:

LinearLayoutManager - це найпоширеніший диспетчер макетів у випадку RecyclerView. Завдяки цьому ми можемо створювати як горизонтальні, так і вертикальні списки прокрутки. StaggeredGridLayoutManager - за допомогою цього менеджера макетів ми можемо створювати поетапні списки. Так само, як екран Pinterest. GridLayoutManager - Цей менеджер макетів може використовуватися для відображення сіток, як і будь-яка галерея зображень.

3. Аніматор предмета

Анімації в списку - це абсолютно новий вимір, який має нескінченні можливості. У ListView як такому немає спеціальних положень, за допомогою яких можна анімувати, додавати або видаляти елементи. Замість цього пізніше, як Android розвивався ViewPropertyAnimator був запропонований Chet Haase від Google у цьому відеоуроці для анімації в ListView.

З іншого боку, порівнюючи Android RecyclerView та ListView, він має клас RecyclerView.ItemAnimator для обробки анімації. За допомогою цього класу можуть бути визначені спеціальні анімації для подій додавання, видалення та переміщення. Крім того, він пропонує DefaultItemAnimator, якщо вам не потрібні будь-які налаштування.

4. Перехідник

Адаптери ListView прості у виконанні. У них був основний метод getView, де відбувалася вся магія. Де погляди були прив'язані до позиції. Також у них був цікавий метод registerDataSetObserver, де можна встановити спостерігача прямо в адаптері. Ця функція також присутня в RecyclerView, але для неї використовується клас RecyclerView.AdapterDataObserver. Але суть на користь ListView полягає в тому, що він підтримує три реалізації за замовчуванням адаптерів:

ArrayAdapter CursorAdapter SimpleCursorAdapter У той час як RecyclerView адаптер має всі функції, які мали адаптери ListView, за винятком вбудованої підтримки DB-курсорів та ArrayLists. В RecyclerView.Adapter зараз ми маємо зробити власну реалізацію для подачі даних в адаптер. Так само, як BaseAdapter робить для ListViews. Хоча, якщо ви хочете дізнатися більше про реалізацію адаптера RecyclerView, зверніться до прикладу Android RecyclerView.

5. Повідомлення про зміну даних

Під час роботи з ListView, якщо набір даних змінено, вам потрібно поновити метод notifyDataSetChanged базового адаптера для оновлення даних. Або встановіть для методу setNotifyOnChange значення true, якщо ви хочете автоматично викликати метод notifyDataSetChanged. Але в обох випадках вихід у списку дуже важкий. В основному він оновлює погляди списку.

Але навпаки, у адаптері RecyclerView, якщо один елемент чи діапазон елементів змінилися, існують методи відповідного повідомлення про зміну. Вони є notifyItemChanged і notifyItemRangeChanged відповідно і багато інших подібних:

notifyItemInsterted notifyItemMoved notifyItemRangeInsterted notifyItemRangeRemoved І звичайно, він має оригінальний метод оновити весь список, тобто notifyDataSetChanged, який повідомляє про адаптований цілий набір даних змінився.

6. Прикраса предмета

Щоб відобразити спеціальні роздільники у ListView, можна було легко додати ці параметри до XML ListView:

XHTML android: delier = "@ android: color / transparent" android: delierHeight = "5dp" 1 2 android: delier = "@ android: color / transparent" android: delierHeight = "5dp" Цікава частина Android RecyclerView: на даний момент він не показує роздільник між елементами за замовчуванням. Хоча хлопці з Google, мабуть, навмисно це покинули. Але це значно збільшує зусилля для розробника. Якщо ви хочете додати роздільник між елементами, можливо, вам доведеться виконати спеціальну реалізацію за допомогою класу RecyclerView.ItemDecoration.

Або ви можете застосувати хак, скориставшись цим файлом з офіційних зразків: DividerItemDecoration.java

7. OnItemTouchListener

Перегляди списків, які використовуються для простої реалізації для виявлення кліків, тобто за допомогою інтерфейсу AdapterView.OnItemClickListener.

Але з іншого боку, інтерфейс RecyclerView.OnItemTouchListener використовується для виявлення сенсорних подій в Android RecyclerView. Це трохи ускладнює реалізацію, але дає більший контроль розробнику щодо перехоплення сенсорних подій. В офіційній документації зазначено, що це може бути корисно для маніпуляцій з жестом, оскільки воно перехоплює сенсорну подію, перш ніж вона буде доставлена ​​RecyclerView.


1

RecyclerView був створений як поліпшення ListView, так що так, ви можете створити доданий список із керуванням ListView, але використовувати RecyclerView простіше:

  1. Повторно використовує комірки під час прокрутки вгору / вниз : це можливо, застосувавши утримувач перегляду в адаптері ListView, але це було необов’язково, тоді як у RecycleView - це стандартний спосіб запису адаптера.

  2. Розв'язує список зі свого контейнера : так ви можете легко розміщувати елементи списку під час виконання роботи в різних контейнерах (linearLayout, gridLayout) з налаштуванням LayoutManager.

mRecyclerView = (RecyclerView) findViewById (R.id.my_recycler_view); mRecyclerView.setLayoutManager (новий LinearLayoutManager (це)); mRecyclerView.setLayoutManager (новий GridLayoutManager (це, 2));

  1. Анімує спільні дії зі списку : анімації розв'язуються та делегуються в ItemAnimator. Про RecyclerView є більше, але я думаю, що ці моменти є основними.

Отже, підсумовуючи, RecyclerView - це більш гнучка система управління "переліковими даними", яка відповідає моделям делегування проблем і залишає для себе лише одне завдання - переробку елементів.


0

Якщо ви використовуєте RecycleView, спочатку вам потрібно більше зусиль для налаштування. Вам потрібно приділити більше часу, щоб налаштувати простий елемент onclick, рамку, подію на дотик та іншу просту річ. Але кінцевий продукт буде ідеальним.

Тож рішення - ваше. Я пропоную, якщо ви розробите такий простий додаток, як завантаження телефонної книги, де достатньо простого клацання елемента, ви можете застосувати перегляд списку. Але якщо ви створюєте домашню сторінку соціальних мереж як необмежену прокрутку. Кілька різних прикрас між предметом, набагато більше керування окремим предметом, ніж використання подання для переробки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.