Перейти к основному содержимому

Списки и Сетки

В FlutterFlow виджеты ListView и GridView — это универсальные инструменты для отображения списков и сеток элементов. Каждый из них легко настраивается и оптимизирован для динамического контента, что делает их незаменимыми для любого приложения, в котором необходимо прокручивать коллекцию элементов, таких как изображения, текст или интерактивные элементы.

Виджет ListView

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

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

Вы можете настроить свойства и функциональность ListView, основные из которых следующие:

Ось (Axis)

Свойство Axis определяет ориентацию ListView. Вы можете выбрать "Vertical" или "Horizontal" в зависимости от того, хотите ли вы, чтобы список прокручивался вертикально или горизонтально.

listview-axis.png

Промежутки (Spacing)

  • Items Spacing: Определяет расстояние между отдельными элементами в ListView. Вы можете задать промежуток в пикселях.

  • Apply to Start & End: При включении промежуток между элементами также применяется к началу и концу ListView, добавляя отступы в начале и конце списка. Это эффективно добавляет паддинг к макету, как между элементами, так и вокруг них.

  • Start Spacing и End Spacing: Эти свойства позволяют задать дополнительные отступы в начале и конце ListView, соответственно. Их можно использовать для создания дополнительного пространства вокруг элементов списка, отличного от промежутков между элементами.

Расширенные функции

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

  • Primary: Если установлено в true, ListView будет основной областью прокрутки в данном контексте. Это обычно влияет на взаимодействие с другими областями прокрутки и на то, растягивается ли он до полного заполнения области. См. подробнее здесь.

  • Reverse: При активации свойства reverse порядок элементов в списке меняется на обратный. Для вертикального списка это означает начало с нижней части, а для горизонтального — начало с правой стороны.

listview-reverse.png

Сделать список переставляемым (Reorderable)

Позволяет ли перестановку элементов в списке. На Web и Desktop это добавит элементы для перетаскивания, но на мобильных устройствах перестановка запускается длительным нажатием на элемент.

Примечание

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

Содержимое переставляемого списка

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

Простое руководство по настройке переставляемого ListView:

Использование переменной состояния приложения (App State variable)
  1. Сначала создайте переменную состояния приложения с несколькими элементами типа String и отобразите их в виджете ListView.

  2. Затем выберите ListView, перейдите в Properties Panel > ListView Properties и включите свойство Reorderable.

  3. Выберите Actions в панели свойств (правое меню) и откройте Action Flow Editor.

  4. Вы увидите триггер действия On Reorder. Действия в этом разделе выполняются, когда пользователь завершает перестановку элемента в интерфейсе. Нам также необходимо обновить позицию элемента в самом списке. Для этого мы можем создать пользовательское действие, которое изменит индекс элемента в списке.

    1. Создайте пользовательское действие с тремя аргументами, которые принимают фактический список, старый индекс и новый индекс. Подсказка: вы получите старый и новый индекс в меню Set Variable > Reorderable ListView.
    2. Пример кода с пояснением:
 // Define a function called reorderItems that returns a Future of a list of strings.
// It takes in a list of strings, an old index, and a new index as parameters.
Future<List<String>> reorderItems(
List<String> list,
int oldIndex,
int newIndex,
) async {
// If the item is being moved to a position further down the list
// (i.e., to a higher index), decrement the newIndex by 1.
// This adjustment is needed because removing an item from its original
// position will shift the indices of all subsequent items.
if (oldIndex < newIndex) {
newIndex -= 1;
}

// Remove the item from its original position in the list and store
// it in the 'item' variable.
final item = list.removeAt(oldIndex);

// Insert the removed item into its new position in the list.
list.insert(newIndex, item);

// Return the modified list.
return list;
}
  1. Специальное действие возвращает модифицированный список, который можно использовать для обновления текущего списка с помощью действия обновления переменной состояния приложения.
Перестановка элементов в запросе Firebase

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

Предупреждение

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

  1. Создайте поле 'order' в коллекции.
  2. Запрашивайте коллекцию, упорядочивая по полю 'order'.
  3. Убедитесь, что функция бесконечной прокрутки отключена.
  4. Замените код пользовательского действия на следующий:
Future reorderFirebaseItems(
List<PlaylistRecord> list,
int oldIndex,
int newIndex,
) async {
// If the item is being moved down the list, we adjust the newIndex.
if (oldIndex < newIndex) {
newIndex -= 1;
}

// Remove the item from its current position in the list.
final PlaylistRecord item = list.removeAt(oldIndex);

// Insert the item into its new position.
list.insert(newIndex, item);

// Create a batch to combine multiple Firestore operations into one.
final batch = FirebaseFirestore.instance.batch();

// Iterate through the list and update the order field for each document in Firestore.
for (int i = 0; i < list.length; i++) {
final PlaylistRecord doc = list[i];
// Update the 'order' field of the document with its new index.
// This assumes that you have an 'order' field in Firestore where you store the order of the items.
batch.update(doc.reference, {
'order': i
});
}

// Commit all the batched operations to Firestore.
return await batch.commit();
}


Виджет ListTile

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

Когда использовать ListTile вместо кастомных компонентов

Используйте ListTile, когда вам требуется простой и эффективный макет со стандартными элементами и взаимодействиями. Это особенно подходит для:

  • Списков с однородной структурой элементов.
  • Быстрого создания функциональных интерфейсов без необходимости сложной настройки.
  • Сценариев, требующих интегрированной обратной связи на касания и функций доступности, которые ListTile предоставляет по умолчанию.

Вы можете настраивать свойства Title (Text), Subtitle (Text) и Icon через панель свойств.

list-tile.png

к сведению

Чтобы узнать, как настраивать виджеты текста в этом компоненте, перейдите по ссылке на Текстовый виджет.

Преобразование в SlidableListTile

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

Вот как можно включить функцию слайда у ListTile и изменить свойства действий:

Виджет GridView

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

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

gridview.png

Ниже представлено краткое демонстрационное видео о том, как добавить виджет GridView и изменить его свойства:

Staggered View

Grid View vs Staggered View

GridView и StaggeredView — это похожие виджеты в FlutterFlow, но с основной разницей в расположении и размере их дочерних элементов. GridView располагает элементы в сетке фиксированного размера, тогда как StaggeredView позволяет размещать элементы разного размера, создавая более гибкий и динамичный макет. StaggeredView идеально подходит для макетов с элементами различных размеров, например, для создания макета, похожего на приложение Pinterest.

staggeredView

Расширенные функции

  • Shrink Wrap: По умолчанию виджет GridView занимает все доступное пространство в своей основной оси. Это значит, что если свойство Axis установлено как Vertical, GridView займет все вертикальное пространство экрана. Аналогично, если Axis установлен как Horizontal, GridView резервирует всё горизонтальное пространство.

  • Primary: Когда этот параметр установлен, он указывает, является ли GridView основным прокручиваемым виджетом в макете. Основной GridView управляет взаимодействиями прокрутки, что обычно необходимо, если в области просмотра присутствует только один виджет прокрутки. Подробнее об этом параметре.

Видеоурок

Если вам удобнее смотреть видеоурок, вот ссылка для вас:

Добавление бесконечной прокрутки

Функция бесконечной прокрутки автоматически загружает новые элементы при прокрутке списка вниз. Она работает, показывая ограниченное количество элементов (например, 15, 25) вначале и загружая следующие элементы, прежде чем пользователь достигнет конца списка. В конце списка отображается индикатор загрузки в виде кольца, пока загружаются новые элементы.

Бесконечная прокрутка за кулисами

Добавление бесконечной прокрутки улучшает пользовательский опыт, сокращая начальное время ожидания (без неё загрузка длинного списка заняла бы больше времени) и подгружая новые элементы только по мере необходимости.

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

Бесконечная прокрутка для списка из коллекции Firestore

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

Чтобы включить бесконечную прокрутку:

  1. Запросите коллекцию в ListView (пропустите этот шаг, если он уже выполнен).
  2. Выберите ListView, перейдите в панель свойств и выберите раздел Backend Query.
  3. Прокрутите вниз до уже добавленного запроса и включите Enable Infinite Scroll.
  4. При включении бесконечной прокрутки также активируется свойство Listen For Changes, благодаря которому список автоматически обновляется при изменении элемента. Это нужно, чтобы все элементы на экране были актуальными, но новые элементы при добавлении или удалении в этом списке не обновляются автоматически.
  5. Элементы подгружаются порциями, называемыми страницами. Количество элементов для загрузки на одной странице определяется свойством Page Size. По умолчанию значение составляет 25 (загружается 25 элементов на странице). ListView загружает первую страницу, как только она становится видимой на экране, а последующие страницы подгружаются при прокрутке. Вы можете настроить это значение в зависимости от требований.
  6. Нажмите Save.

Бесконечная прокрутка для списка из API-вызова

Чтобы добавить бесконечную прокрутку для API-вызова, необходимо использовать конечную точку, которая поддерживает пагинацию и включает хотя бы один параметр запроса для указания номера страницы (например, page, offset и т.д.).

Переменные пагинации

При добавлении постраничного API-вызова с бесконечной прокруткой вам предоставляются следующие переменные пагинации, которые можно использовать в переменных API. Эти переменные доступны в меню Set Variable.

Переменные пагинации

  1. Next Page Index: Используется в параметре запроса, который принимает номер страницы. Значение по умолчанию — 0 и увеличивается на единицу при прокрутке вниз, пока не достигнет конца списка.
  2. #(Количество) Загруженных элементов: Равняется количеству элементов, возвращённых API-вызовом с пагинацией.
  3. Последний ответ: Полезно для получения данных из последнего ответа, которые помогут извлечь следующий набор данных.
подсказка

При передаче Количество загруженных элементов для параметров запроса, таких как limit, per_page, size и т.д., используйте конкретное значение, например, 15 или 20.

Добавление бесконечной прокрутки включает следующие шаги:

  1. Добавьте API-вызов с пагинацией
  2. Передача переменной пагинации в запрос API-вызова

1. Добавьте API-вызов с пагинацией

API с пагинацией возвращает результат частями. Большинство API с пагинацией требуют добавления параметров запроса для указания количества элементов для извлечения и начала.

Например, API-вызов https://reqres.in/api/users?per_page=20&page=1 требует параметр per_page, определяющий 20 элементов на страницу, а параметр page указывает на начало с первой страницы. Этот метод называется постраничной пагинацией.

См. как добавить API с пагинацией, добавляя параметры запроса.

2. Передача переменной пагинации в запрос API-вызова

Этот шаг включает добавление виджета ListView -> ListTile и запрос API с пагинацией.

  1. Сначала запросите и отобразите данные из API.
  2. При запросе API передайте значение параметра запроса из переменной пагинации.

Свойство Primary

Когда это свойство включено, даже если содержимое внутри прокручиваемого виджета, такого как ListView или GridView, не превышает видимую область, пользователь может попытаться его прокрутить. Контент может слегка смещаться и затем возвращаться, что особенно заметно на iOS с эффектом отскока.

подсказка

В ситуациях, когда у вас есть несколько вложенных прокручиваемых виджетов, обычно только один должен быть установлен как основной.

В большинстве случаев внешнему прокручиваемому виджету (обычно занимающему больше всего пространства или весь экран) устанавливается значение primary, а внутренние прокручиваемые виджеты не являются основными. Например, в структуре виджетов Column > ListView следует оставить Column основным, а ListView — не основным.

img_2.png

Обновление списка (Pull to Refresh) для ListView или GridView

Если для Backend Query в прокручиваемом виджете включён параметр Single Time Query, список не будет обновляться при изменении элементов на сервере. Чтобы устранить это, добавьте функцию обновления по жесту pull-to-refresh.

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

Как включить обновление списка

  1. Выберите прокручиваемый виджет, такой как ListView, GridView или StaggeredView.
  2. Перейдите в панель свойств и выберите Backend Query.
  3. Откройте уже добавленный запрос (например, запрос коллекции или вызов API) и убедитесь, что Single Time Query включен.
  4. Включите переключатель Enable Pull to Refresh. Это автоматически добавит действие Refresh Database Request на жест обновления списка.

Прокрутка к началу или концу (Scroll To [Action])

С помощью этого действия можно прокрутить виджет до начала или конца списка.

к сведению

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

Следуйте приведенным ниже шагам, чтобы добавить это действие к любому виджету.

  1. Выберите Виджет (например, FloatingActionButton), для которого вы хотите добавить действие.
  2. Перейдите в панель Actions (меню справа) и нажмите + Add Action.
  3. Найдите и выберите Scroll To (в разделе Widget/UI Interactions).
  4. Установите Scrollable Widget to Control в название прокручиваемого виджета (например, ListView), добавленного на вашу страницу.
  5. Установите Scroll To на Beginning (для прокрутки к началу) или End (для прокрутки к концу) списка.
  6. Укажите Duration в миллисекундах (например, 1000мс = 1 секунда). Это определяет, сколько времени потребуется для завершения анимации прокрутки. Совет: Если вы ожидаете, что список будет длинным, рассмотрите возможность установки более короткой длительности.