Подробное изучение виджета ListView и его особенностей.
Некоторое время назад я написал статью об основах использования ListView и GridView во Flutter. Эта статья предназначена для более детального изучения класса ListView, ScrollPhysics, а также параметров конфигурирования и оптимизаций для общего виджета.
ListView во Flutter представляет собой линейный список прокручиваемых элементов. Мы можем использовать его для создания прокручиваемого списка или списка повторяющихся элементов.
Изучение типов ListView
Мы начнем с рассмотрения типов ListViews, а позже рассмотрим другие возможности и усовершенствования для него.
Рассмотрим типы ListViews:
-
ListView
-
ListView.builder
-
ListView.separated
-
ListView.custom
Давайте исследовать эти типы один за другим:
ListView
Это дефолтный конструктор класса ListView. ListView просто берет список дочерних элементов и делает из него список с возможностью прокрутки.
Список, построенный с использованием конструктора по умолчаниюОбщий формат кода:
ListView( children: <Widget>[ ItemOne(), ItemTwo(), ItemThree(), ],),
ListView.builder()
Конструктор builder()
строит повторяющийся список
элементов. Конструктор принимает два основных параметра:
itemCount для подсчета количества элементов в
списке и itemBuilder конструктор для каждого
построенного элемента списка.
Общий формат кода:
ListView.builder( itemCount: itemCount, itemBuilder: (context, position) { return listItem(); },),
Хитрый трюк: так как они загружаются не сразу и только необходимое количество, нам на самом деле не нужно, чтобы item Count (счетчик элементов) был в качестве обязательного параметра, таким образом список может быть бесконечным.
ListView.builder( itemBuilder: (context, position) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Text(position.toString(), style: TextStyle(fontSize: 22.0),), ), ); },),
ListView без параметра ItemCount
ListView.separated()
В конструкторе separated()
мы генерируем список и
можем указать разделитель между каждым элементом.
По сути, мы строим два переплетенных списка: один как основной, другой как разделительный.
Обратите внимание, что бесконечный счетчик, обсуждавшийся в
предыдущем конструкторе, не может быть использован здесь. Этот
конструктор принудительно приводит в действие счетчик элементов
itemCount
.
Код для этого типа идет как:
ListView.separated( itemBuilder: (context, position) { return ListItem(); }, separatorBuilder: (context, position) { return SeparatorItem(); }, itemCount: itemCount,),
Этот тип списка позволяет динамически определять разделители, иметь различные типы разделителей для различных типов элементов, добавлять или удалять разделители по мере необходимости и т.д.
Данная реализация также может быть использована для вставки других типов элементов (например, рекламы) легко и без внесения каких-либо изменений в основной список в середине элементов списка.
Пример показывает рекламу, когда Position делится на 4Примечание: Длина списка разделителей на 1 единицу меньше, чем список элементов, так как после последнего элемента разделитель не ставится.
ListView.custom()
Конструктор custom()
, как подсказывает его
название, позволяет создавать ListViews с с индивидуальными
функциональными возможностями для построения дочерних элементов
списка. Основным параметром, необходимым для этого, является
SliverChildDelegate
, который формирует компоненты.
Существуют следующие типы SliverChildDelegates
:
-
SliverChildListDelegate
-
SliverChildBuilderDelegate .
SliverChildListDelegate
принимает прямой дочерний
список, в то время как SliverChildBuiderDelegate
принимает IndexedWidgetBuilder
(Функция сборщика,
которую мы используем).
Вы можете использовать или разбить их на подклассы для создания собственных участников списка.
ListView.builder по сути является ListView.custom с функцией SliverChildBuilderDelegate.
Конструктор по умолчанию ListView ведет себя как ListView.custom с SliverChildListDelegate.
Теперь, когда мы закончили с типами ListViews, давайте взглянем на ScrollPhysics.
Изучение ScrollPhysics
Для управления прокруткой мы устанавливаем физический параметр в конструкторе ListView. Различные типы этого параметра:
NeverScrollableScrollPhysics .
NeverScrollScrollPhysics
запрещает прокрутку
списка. Используйте это, чтобы полностью отключить прокрутку
ListView.
BouncingScrollPhysics .
BouncingScrollPhysics
возвращает список обратно,
когда список заканчивается. Аналогичный эффект используется на
iOS.
ClamppingScrollPhysics
Это функция прокрутки, которая по умолчанию используется на Android. Список останавливается в конце и показывает индикацию этого действия.
FixedExtentScrollPhysics
Это немного отличается от других списков в том смысле, что
работает только с FixedExtendScrollControllers
и
списками, которые их используют. Для примера возьмём
ListWheelScrollView
, который делает список,
напоминающий по форме колесо.
FixedExtentScrollPhysics
только прокручивает
элементы вместо любого смещения между ними.
Код для этого примера невероятно прост:
FixedExtentScrollController fixedExtentScrollController = new FixedExtentScrollController();ListWheelScrollView( controller: fixedExtentScrollController, physics: FixedExtentScrollPhysics(), children: monthsOfTheYear.map((month) { return Card( child: Row( children: <Widget>[ Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( month, style: TextStyle(fontSize: 18.0), ), )), ], )); }).toList(), itemExtent: 60.0,),
Ещё несколько вещей, которые нужно знать.
Как сохранить элементы, которые удаляются при работе со списком ?
Flutter позволяет использовать виджет KeepAlive(), сохраняющий
элемент, который в противном случае был бы удален. В списке
элементы по умолчанию встроены в виджет
AutomaticKeepAlive
.
AutomaticKeepAlives
можно отключить, установив в
поле addAutomaticKeepAlives
значение
false
. Это полезно в тех случаях, когда элементы не
нуждаются в сохранении или в пользовательской версии
KeepAlive
.
Почему мой ListView имеет отступ между списком и внешним виджетом?
По умолчанию ListView имеет отступ между списком и внешним виджетом, чтобы удалить его, установите EdgeInsets.all(0.0).
Вот и все для этой статьи!
Надеюсь, вам понравилось.
Продолжайте следить за мной, чтобы узнать больше о Flutter, оставляйте свои мнения и комментарии.
Перевод статьи подготовлен в преддверии старта курсаFlutter Mobile Developer.
В преддверии старта курса приглашаем всех желающих записаться на бесплатны демо-урок по теме:Графика во Flutter.
На уроке участники вместе с экспертом-ведущим разберут, как устроен рендеринг во Flutter и изучат основные компоненты библиотекиdart:ui
.