Подробное изучение виджета 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.separated()
В конструкторе separated() мы генерируем список и можем указать разделитель между каждым элементом.

По сути, мы строим два переплетенных списка: один как основной, другой как разделительный.
Обратите внимание, что бесконечный счетчик, обсуждавшийся в предыдущем конструкторе, не может быть использован здесь. Этот конструктор принудительно приводит в действие счетчик элементов itemCount.
Код для этого типа идет как:
ListView.separated( itemBuilder: (context, position) { return ListItem(); }, separatorBuilder: (context, position) { return SeparatorItem(); }, itemCount: itemCount, ),
Этот тип списка позволяет динамически определять разделители, иметь различные типы разделителей для различных типов элементов, добавлять или удалять разделители по мере необходимости и т.д.
Данная реализация также может быть использована для вставки других типов элементов (например, рекламы) легко и без внесения каких-либо изменений в основной список в середине элементов списка.
Примечание: Длина списка разделителей на 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.

