Подробное изучение виджета ListView и его функций

Некоторое время назад я написал статью об основах использования ListView и GridView во Flutter. Эта статья предназначена для более подробного изучения класса ListView, ScrollPhysics, а также настроек и оптимизаций для общего виджета.

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

Изучение типов ListView

Мы начнем с рассмотрения типов ListView, а затем рассмотрим другие функции и их аккуратные модификации.

Давайте посмотрим на типы ListView:

  1. ListView
  2. ListView.builder
  3. ListView.separated
  4. ListView.custom

Давайте рассмотрим эти типы один за другим:

Посмотреть список

Это конструктор по умолчанию для класса ListView. ListView просто берет список дочерних элементов и делает его прокручиваемым.

Общий формат кода:

ListView(
  children: <Widget>[
    ItemOne(),
    ItemTwo(),
    ItemThree(),
  ],
),

Обычно это следует использовать с небольшим количеством дочерних элементов, поскольку список также будет создавать невидимые элементы в списке, а большое количество элементов может сделать это неэффективным.

ListView.builder ()

Конструктор builder () создает повторяющийся список элементов. Конструктор принимает два основных параметра: itemCount для количества элементов в списке и itemBuilder для каждого созданного элемента списка.

Общий формат кода:

ListView.builder(
  itemCount: itemCount,
  itemBuilder: (context, position) {
    return listItem();
  },
),

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

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

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 ()

В конструкторе separator () мы создаем список и можем указать разделитель между каждым элементом.

По сути, мы создаем два переплетенных списка: один как основной список, другой как список-разделитель.

Обратите внимание, что бесконечный счетчик, описанный в предыдущем конструкторе, здесь не может быть использован, и этот конструктор применяет itemCount.

Код этого типа выглядит так:

ListView.separated(
      itemBuilder: (context, position) {
        return ListItem();
      },
      separatorBuilder: (context, position) {
        return SeparatorItem();
      },
      itemCount: itemCount,
),

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

Эту реализацию также можно использовать для вставки других типов элементов (например, рекламы) легко и без каких-либо изменений в основной список в середине элементов списка.

Примечание. Длина списка разделителей на 1 меньше, чем у списка элементов, поскольку разделителя после последнего элемента не существует.

ListView.custom ()

Конструктор custom (), как следует из его названия, позволяет создавать ListView с настраиваемыми функциями для построения дочерних элементов списка. Основным параметром, необходимым для этого, является SliverChildDelegate, который создает элементы. Типы SliverChildDelegates:

  1. SliverChildListDelegate
  2. SliverChildBuilderDelegate

SliverChildListDelegate принимает прямой список дочерних элементов, тогда как SliverChildBuiderDelegate принимает IndexedWidgetBuilder (функцию построения, которую мы используем).

Вы можете использовать их или создать подклассы для создания собственных делегатов.

ListView.builder по сути является ListView.custom с SliverChildBuilderDelegate.

Конструктор ListView по умолчанию ведет себя как ListView.custom с SliverChildListDelegate.

Теперь, когда мы закончили с типами ListViews, давайте взглянем на ScrollPhysics.

Изучение ScrollPhysics

Чтобы контролировать способ прокрутки, мы устанавливаем параметр физика в конструкторе ListView. Различные типы физики:

NeverScrollableScrollPhysics

NeverScrollableScrollPhysics делает список недоступным для прокрутки. Используйте это, чтобы полностью отключить прокрутку ListView.

BouncingScrollФизика

BouncingScrollPhysics возвращает список обратно, когда список заканчивается. Аналогичный эффект используется на iOS.

Зажимная прокруткаФизика

Это физика прокрутки по умолчанию, используемая на 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 и комментировать любые отзывы об этой статье.

Другие мои статьи