Списки и сетки
В FlutterFlow виджеты ListView и GridView представляют собой универсальные компоненты, предназначенные для отображения списков и сеток элементов соответственно. Оба виджета высоко настраиваемы и оптимизированы для динамического отображения содержимого, что делает их незаменимыми для приложений, где требуется прокрутка коллекции элементов, таких как изображения, текст или интерактивные компоненты.
Виджет ListView
ListView — это прокручиваемый список виджетов, расположенных линейно. Он идеально подходит для сценариев, где элементы нужно отображать последовательно, вертикально или горизонтально.
Он особенно полезен для длинных списков, требующих высокой производительности; рендерится только те элементы, которые видны на экране, что повышает эффективность для списков с большим количеством элементов.
Вы можете настроить свойства и функции ListView, некоторые из них описаны ниже:
Axis
Свойство Axis определяет ориентацию ListView. Вы можете выбрать "Vertical" или "Horizontal" в зависимости от того, хотите ли вы, чтобы список прокручивался вертикально или горизонтально.

Spacing
- Items Spacing: Это определяет рассто яние между отдельными элементами в ListView. Вы можете указать расстояние в пикселях.
Предпочтительнее использовать "Items Spacing", установленное на родительском Row или Column, вместо padding на отдельных элементах. Это обеспечивает согласованность, особенно для списков, не генерируемых динамически.
-
Apply to Start & End: При активации расстояние между элементами также применяется к началу и концу ListView, добавляя отступы в начале и конце списка. Это эффективно добавляет padding в начале и конце макета в дополнение к расстоянию между элементами.
-
Start Spacing and End Spacing: Эти свойства позволяют установить дополнительное расстояние в начале и конце ListView соответственно. Это можно и спользовать для создания отступов вокруг элементов списка, отличных от расстояния между ними.
Advanced Functionalities
-
Shrink Wrap: При активации этого свойства ListView подстраивается под общий размер своих дочерних элементов, то есть не занимает больше места, чем необходимо. Это полезно для списков, которые не требуют прокрутки, поскольку помещаются в заданные ограничения.
-
Primary: Если установлено в true, ListView выступает в роли основного прокручиваемого представления в контексте. Это обычно влияет на взаимодействие представления с другими прокручиваемыми элементами и на то, растягивается ли оно для заполнения области просмотра. Подробнее здесь.
-
Reverse: В списках при активации свойства reverse порядок появления элементов в ListView меняется на обратный. Для вертикального списка это означает начало с низа, а для горизонтального — с правой стороны.

Reorderable List
Разрешить ли переупорядочивание элементов в списке. На веб- или десктопной платформе это добавит ручки для перетаскивания, но на мобильных устройствах переупорядочивание запускается долгим нажатием на элемент.
Это не сохраняет порядок элементов в списке автоматически, но позволяет определить действие в триггере "On Reorder", чтобы внести необходимые изменения самостоятельно.
Reorderable ListView должен иметь динамических дочерних элементов, иначе активация этого свойства вызовет ошибку.
Вот краткий урок по настройке Reorderable ListView:
Using App State variable
-
Сначала создайте переменную состояния приложения с несколькими элементами типа String и отобразите их в виджете ListView.
-
Затем выберите ListView, перейдите в Properties Panel > ListView Properties и активируйте свойство Reorderable.
-
Выберите Actions в панели свойств (правое меню) и откройте Action Flow Editor.
-
Вы увидите триггер действия On Reorder. Действия под ним срабатывают, когда пользователь завершает перемещение элемента в интерфейсе. Но также нужно обновить позицию элемента в самом списке. Для этого можно создать пользовательское действие, которое изменит индекс элемента в списке.
- Создайте пользовательское действие с тремя аргументами, принимающими исходный список, старый индекс и новый индекс. Совет: Старый и новый индексы можно получить из меню Set Variable > Reorderable ListView.
- Вот пользовательский код с объяснением
// 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;
}
- Пользовательское действие возвращает измененный список, который можно использовать для обновления исходного списка с помощью действия обновления переменной состояния приложения.
Reordering Items in a Firebase Query
Если вы хотите переупорядочить элементы списка, полученные через запрос коллекции Firebase, шаги почти аналогичны, за исключением следующих изменений.
Переупорядочивание элементов в запросе Firebase подходит только для небольших списков. Для больших наборов данных этот метод может быть неэффективным и привести к проблемам производительности. Кроме того, частые записи и обновления в Firebase могут значительно увеличить затраты.
- Создайте поле 'order' в коллекции.
- Запросите коллекцию, упорядочив по полю 'order'.
- Убедитесь, что бесконечная прокрутка отключена.
- Замените код пользовательского действия на следующий:
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 предоставляет по умолчанию.
Вы можете настроить свойства Title (Text), Subtitle (Text) и Icon в панели свойств.

Чтобы узнать, как настроить текстовые виджеты в этом компоненте, обратитесь к Text widget.
Convert into SlidableListTile
ListTile в FlutterFlow предлагает дополнительную функцию — его легко можно преобразовать в раздвижную версию. Этот улучшенный ListTile позволяет встроить действия, к которым пользователи могут получить доступ, сдвинув плитку влево, добавляя слой интерактивности и удобства к стандартному элементу списка.
Вот как активировать функцию Slidable для ListTile и изменить свойства действий:
Виджет GridView
GridView предоставляет двумерный массив дочерних элементов. Это виджет выбора, когда нужно отображать элементы в сеточном узоре, например, в галерее фото или макете настольной игры.
Как и ListView, GridView рендерит только видимые элементы, что делает его эффективным для отображения больших коллекций. GridView поддерживает несколько конфигураций для количества столбцов, расстояний, соотношения сторон и направлений прокрутки, предлагая надежные варианты настройки для разнообразных потребностей макета.

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

Advanced Functionalities
-
Shrink Wrap: По умолчанию виджет GridView занимает все доступное пространство по главной оси. Это значит, что если свойство Axis установлено в Vertical, GridView займет все вертикальное пространство на экране. Аналогично, если Axis установлено в Horizontal, GridView зарезервирует все горизонтальное пространство.
-
Primary: При установке это указывает, является ли GridView основным прокручиваемым виджетом в макете. Основной GridView обрабатывает взаимодействия прокрутки, что обычно необходимо, когда в области просмотра есть только одно прокручиваемое представление. Подробнее здесь.
Если вы предпочитаете видеоурок, вот он для вас:
Добавление бесконечной прокрутки
Бесконечная прокрутка автоматически загружает новые элементы при прокрутке вниз списка. Она работает, показывая сначала ограниченное количество элементов (например, 15 или 25) и загружая послед ующие элементы до того, как пользователь достигнет конца списка. В конце списка отображается круговой индикатор прогресса во время загрузки новых элементов.

Добавление бесконечной прокрутки улучшает пользовательский опыт, сокращая начальное время ожидания (без бесконечной прокрутки загрузка длинного списка заняла бы больше времени) и загружая новые элементы только по мере необходимости.
Бесконечную прокрутку можно добавить к списку элементов, полученных из двух источников:
- Бесконечная прокрутка для списка из коллекции Firestore
- Бесконечная прокрутка для списка из вызова API
Infinite scroll on a list from the Firestore collection
В FlutterFlow вы можете напрямую активировать бесконечную прокрутку для списка элементов, полученных из коллекции Firestore.
Чтобы активировать бесконечную прокрутку:
- Запросите коллекцию в ListView (пропустите, если уже сделано).
- Выберите ListView, перейдите в панель свойств и выберите раздел Backend Query.
- Прокрутите вниз уже добавленный запрос и активируйте Enable Infinite Scroll.
- При активации бесконечной прокрутки также активируется свойство Listen For Changes. Это значит, что список автоматически обновляется при изменениях в элементах. Это делается для поддержания актуальности всех элементов на экране. Однако список не обновляется при добавлении или удалении новых элементов. В редких случаях может потребоваться отключить эту функцию. Для этого деактивируйте свойство.
- В бесконечной прокрутке элементы загружаются порциями, называемыми страницами. Количество элементов на одной странице определяется свойством Page Size. По умолчанию значение равно 25 (т.е. загружать 25 элементов на страницу). ListView загружает первую страницу сразу после появления на экране, а последующие страницы (с количеством элементов, указанным в Page Size) загружаются при прокрутке вниз. Вы можете скорректировать это значение в соответствии с дизайном и требованиями.
- Нажмите Save.
Infinite scroll on a list from API call
Чтобы добавить бесконечную прокрутку к вызову API, у вас должен быть эндпоинт, поддерживающий пагинацию с хотя бы одним параметром запроса, принимающим номер страницы, таким как page, offset и т.д.
Pagination Variables
При добавлении пагинированного вызова API вビルдер и активации бесконечной прокрутки мы предоставляем следующие переменные пагинации, которые вы можете передать в переменные API. Они будут доступны в меню Set Variable.

- Next Page Index: Вы можете передать эту переменную для параметра запроса, принимающего номер страницы. Значение по умолчанию — 0, и оно увеличивается на единицу при прокрутке вниз списка до достижения конца.
- #(Number of) Loaded Items: Это равно количеству элементов, возвращенных пагинированным вызовом API.
- Last Response: Это полезно, если вы хотите получить что-то из последнего ответа, что может помочь извлечь следующий набор данных.
При передаче Number of Loaded Items для параметров запроса, таких как limit, per_page, size и т.д., используйте Specific Value, например 15 или 20.
Добавление бесконечной прокрутки включает:
1. Add paginated API call
Пагинированный API — это API, который возвращает результаты порциями. Большинство пагинированных API требуют добавления параметров запроса, чтобы знать, сколько элементов извлекать и с какого места начинать.
Например, этот вызов API https://reqres.in/api/users?per_page=20&page=1 требует параметр per_page, который указывает на загрузку 20 элементов на страницу, и параметр page, который указывает на начало с первой страницы. Это называется пагинацией на основе страниц.
См. как добавить пагинированный API, добавив параметры запроса.
2. Passing pagination variable in API call query
Этот шаг включает добавление ListView -> ListTile виджета и запрос пагинированного вызова API.
- Сначала запросите и отобразите данные из вызовов API.
- При запросе вызова API передайте значение параметра запроса из переменной пагинации.
Primary property
Когда это свойство установлено в true, даже если содержимое внутри прокручиваемого виджета, такого как ListView или GridView, не выходит за пределы видимой области, пользователь все равно может попытаться прокрутить его. Содержимое может слегка сдвинуться и затем вернуться на место, что особенно заметно на iOS с эффектом отскока.
В ситуациях, когда у вас несколько вложенных прокручиваемых виджетов, только один из них обычно должен быть установлен как primary.
В большинстве случаев внешний прокручиваемый виджет (обычно тот, который занимает больше всего места или в есь экран) устанавливается как primary, в то время как внутренние прокручиваемые — нет. Например, при структуре виджетов Column > ListView Column следует оставить как primary, а ListView — как non-primary.

Pull to Refresh on ListView or GridView
Если вы активировали Single Time Query для Backend Query в прокручиваемом виджете, список не обновится при изменениях элементов в бэкенде. Чтобы решить эту проблему, добавьте функцию pull-to-refresh.
Этот шаблон пользовательского интерфейса позволяет пользователям вручную обновлять содержимое, потянув за область содержимого, такую как список. При достаточном потягивании вниз и отпускании приложение обновится, загрузив последние данные или обновления.
Чтобы активировать pull to refresh:
- Выберите свой прокручиваемый виджет, такой как
ListView,GridViewилиStaggeredView. - Перейдите в панель свойств и выберите Backend Query.
- Откройте уже добавленный запрос (например, Query collection или API call) и убедитесь, что Single Time Query активировано.
- Активируйте переключатель Enable Pull to Refresh. Это автоматически добавит действие Refresh Database Request на жест pull to refresh.
Scroll To [Action]
С помощью этого действия вы прокручиваете прокручиваемый виджет к началу или концу.
Перед добавлением этого действия убедитесь, что у вас есть прокручиваемый виджет, такой как ListView, StaggeredView или GridView, с достаточным количеством элементов для активации прокрутки.
Следуйте шагам ниже, чтобы добавить это действие к любому виджету.
- Выберите Widget (например, FloatingActionButton), к которому хотите добавить действие.
- Выберите Actions в панели свойств (правое меню) и нажмите + Add Action.
- Найдите и выберите действие Scroll To (в разделе Widget/UI Interactions).
- Установите Scrollable Widget to Control в имя прокручиваемого виджета (например, ListView), добавленного на вашу страницу.
- Установ ите Scroll To в Beginning (для прокрутки к началу) или End (для прокрутки к концу) списка.
- Укажите Duration в миллисекундах (т.е. 1000 мс = 1 секунда). Это определяет, сколько времени займет анимация прокрутки. Совет: Если ожидается длинный список, рассмотрите установку меньшей длительности.