Списки и Сетки
В FlutterFlow виджеты ListView
и GridView
— это универсальные инструменты для отображения списков и сеток элементов. Каждый из них легко настраивается и оптимизирован для динамического контента, что делает их незаменимыми для любого приложения, в котором необходимо прокручивать коллекцию элементов, таких как изображения, текст или интерактивные элементы.
Виджет ListView
ListView
представляет собой скроллируемый список виджетов, расположенных линейно. Он идеально подходит для случаев, когда элементы должны отображаться один за другим, будь то вертикально или горизонтально.
Этот виджет особенно полезен для длинных списков, где важна эффективность; рендерятся только видимые на экране элементы, что повышает производительность при большом количестве элементов.
Вы можете настроить свойства и функциональность ListView, основные из которых следующие:
Ось (Axis)
Свойство Axis определяет ориентацию ListView. Вы можете выбрать "Vertical" или "Horizontal" в зависимости от того, хотите ли вы, чтобы список прокручивался вертикально или горизонтально.
Промежутки (Spacing)
-
Items Spacing: Определяет расстояние между отдельными элементами в ListView. Вы можете задать промежуток в пикселях.
-
Apply to Start & End: При включении промежуток между элементами также применяется к началу и концу ListView, добавляя отступы в начале и конце списка. Это эффективно добавляет паддинг к макету, как между элементами, так и вокруг них.
-
Start Spacing и End Spacing: Эти свойства позволяют задать дополнительные отступы в начале и конце ListView, соответственно. Их можно использовать для создания дополнительного пространства вокруг элементов списка, отличного от промежутков между элементами.
Расширенные функции
-
Shrink Wrap: При включении ListView будет занимать т олько необходимое пространство, подгоняя размер под общее количество своих дочерних элементов. Это полезно для списков, которые не нуждаются в прокрутке, так как они полностью помещаются в заданные ограничения.
-
Primary: Если установлено в true, ListView будет основной областью прокрутки в данном контексте. Это обычно влияет на взаимодействие с другими областями прокрутки и на то, растягивается ли он до полного заполнения области. См. подробнее здесь.
-
Reverse: При активации свойства reverse порядок элементов в списке меняется на обратный. Для вертикального списка это означает начало с нижней части, а для горизонтального — начало с правой стороны.
Сделать список переставляемым (Reorderable)
Позволяет ли перестановку элементов в списке. На Web и Desktop это добавит элементы для перетаскивания, но на мобильных устройствах перестановка запускается длительным нажатием на элемент.
Это автоматически не сохранит порядок элементов в списке, но позволяет задать действие в разделе "On Reorder", чтобы внести нужные изменения самостоятельно.
Переставляемый ListView должен иметь динамиче ские дочерние элементы, в противном случае включение этой опции приведет к ошибке.
Простое руководство по настройке переставляемого ListView:
Использование переменной состояния приложения (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;
}
- Специальное действие возвращает модифицированный список, который можно использовать для обновления текущего списка с помощью действия обновления переменной состояния приложения.
Перестановка элементов в запросе Firebase
Если вы хотите изменить пор ядок элементов списка, полученных через коллекцию запросов 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 через панель свойств.
Чтобы узнать, как настраивать виджеты текста в этом компоненте, перейдите по ссылке на Текстовый виджет.
Преобразование в SlidableListTile
В FlutterFlow ListTile
можно легко превратить в слайд-версию. Этот улучшенный ListTile
позволяет добавлять действия, доступные пользователям при слайде строки влево, добавляя уровень интерактивности и удобства к стандартному элементу списка.
Вот как можно включить функцию слайда у ListTile
и изменить свойства действий:
Виджет GridView
GridView предоставляет двумерный массив элементов и идеально подходит для отображения объектов в виде сетки, как, например, в галерее изображений или в макете настольной игры.
Как и ListView, GridView рендерит только видимые элементы, что делает его эффективным для отображения больших коллекций. GridView поддерживает различные настройки количества колонок, расстояний между элементами, соотношения сторон и направлений прокрутки, предлагая широкие возможности для настройки макета под различные нужды.
Ниже представлено краткое демонстрационное видео о том, как добавить виджет GridView и изменить его свойства:
Staggered View
GridView и StaggeredView — это похожие виджеты в FlutterFlow, но с основной разницей в расположении и размере их дочерних элементов. GridView располагает элементы в сетке фиксированного размера, тогда как StaggeredView позволяет размещать элементы разного размера, создавая более гибкий и динамичный макет. StaggeredView идеально подходит для макетов с элементами различных размеров, например, для создания макета, похожего на приложение Pinterest.
Расширенные функции
-
Shrink Wrap: По умолчанию виджет GridView занимает все доступное пространство в своей основной оси. Это значит, что если свойство Axis установлено как Vertical, GridView займет все вертикальное пространство экрана. Аналогично, если Axis установлен как Horizontal, GridView резервирует всё горизонтальное пространство.
-
Primary: Когда этот параметр установлен, он указывает, является ли GridView основным прокручиваемым виджетом в макете. Основной GridView управляет взаимодействиями прокру тки, что обычно необходимо, если в области просмотра присутствует только один виджет прокрутки. Подробнее об этом параметре.
Если вам удобнее смотреть видеоурок, вот ссылка для вас:
Добавление бесконечной прокрутки
Функци я бесконечной прокрутки автоматически загружает новые элементы при прокрутке списка вниз. Она работает, показывая ограниченное количество элементов (например, 15, 25) вначале и загружая следующие элементы, прежде чем пользователь достигнет конца списка. В конце списка отображается индикатор загрузки в виде кольца, пока загружаются новые элементы.
Добавление бесконечной прокрутки улучшает пользовательский опыт, сокращая начальное время ожидания (без неё загрузка длинного списка заняла бы больше времени) и подгружая новые элементы только по мере необходимости.
Бесконечную прокрутку можно добавить к списку элементов, полученных из двух источников:
- Бесконечная прокрутка для списка из коллекции Firestore
- Бесконечная прокрутка для списка из API-вызова
Бесконечная прокрутка для списка из коллекции Firestore
В FlutterFlow можно напрямую включить бесконечную прокрутку для списка элементов, полученных из коллекции Firestore.
Чтобы включить бесконечную прокрутку:
- Запросите коллекцию в ListView (пропустите этот шаг, если он уже выполнен).
- Выберите ListView, перейдите в панель свойств и выберите раздел Backend Query.
- Прокрутите вниз до уже добавленного запроса и включите Enable Infinite Scroll.
- При включении бесконечной прокрутки также активируется свойство Listen For Changes, благодаря которому список автоматически обновляется при изменении элемента. Это нужно, чтобы все элементы на экране были актуальными, но новые элементы при добавлении или удалении в этом списке не обновляются автоматически.
- Элементы подгружаются порциями, называемыми страницами. Количество элементов для загрузки на одной странице определяется свойством Page Size. По умолчанию значение составляет 25 (загружается 25 элементов на странице). ListView загружает первую страницу, как только она становится видимой на экране, а последующие страницы подгружаются при прокрутке. Вы можете настроить это значение в зависимости от требований.
- Нажмите Save.
Бесконечная прокрутка для списка из API-вызова
Чтобы добавить бесконечную прокрутку для API-вызова, необходимо использовать конечную точку, которая поддерживает пагинацию и включает хотя бы один параметр запроса для указания номера страницы (например, page, offset и т.д.).
Переменные пагинации
При добавлении постраничного API-вызова с бесконечной прокруткой вам предоставляются следующие переменные пагинации, которые можно использовать в переменных API. Эти переменные доступны в меню Set Variable.
- Next Page Index: Используется в параметре запроса, который принимает номер страницы. Значение по умолчанию — 0 и увеличивается на единицу при прокрутке вниз, пока не достигнет конца списка.
- #(Количество) Загруженных элементов: Равняется количеству элеме нтов, возвращённых API-вызовом с пагинацией.
- Последний ответ: Полезно для получения данных из последнего ответа, которые помогут извлечь следующий набор данных.
При передаче Количество загруженных элементов для параметров запроса, таких как limit, per_page, size и т.д., используйте конкретное значение, например, 15 или 20.
Добавление бесконечной прокрутки включает следующие шаги:
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 с пагинацией.
- Сначала запросите и отобразите данные из API.
- При запросе API передайте значение параметра запроса из переменной пагинации.
Свойство Primary
Когда это свойство включено, даже если содержимое внутри прокручиваемого виджета, такого как ListView или GridView, не превышает видимую область, пользователь может попытаться его прокрутить. Контент может слегка смещаться и затем возвращаться, что особенно заметно на iOS с эффектом отскока.
В ситуациях, когда у вас есть несколько вложенных прокручиваемых виджетов, обычно только один должен быть установлен как основной.
В большинстве случаев внешнему прокручиваемому виджету (обычно занимающему больше всего пространства или весь экран) устанавливается значение primary, а внутренние прокручиваемые виджеты не являются основными. Например, в структуре виджетов Column > ListView следует оставить Column основным, а ListView — не основным.
Обновление списка (Pull to Refresh) для ListView или GridView
Если для Backend Query в прокручиваемом виджете включён параметр Single Time Query, список не будет обновляться при изменении элементов на сервере. Чтобы устранить это, добавьте функцию обновления по жесту pull-to-refresh.
Эта модель интерфейса позволяет пользователям вручную обновить контент, потянув вниз область контента, такую как список. После достаточного смещения вниз и отпускания приложение обновится, получая последние данные или обновления.
Как включить обновление списка
- Выберите прокручиваемый виджет, такой как
ListView
,GridView
илиStaggeredView
. - Перейдите в панель свойств и выберите Backend Query.
- Откройте уже добавленный запрос (например, запрос коллекции или вызов API) и убедитесь, что Single Time Query включен.
- Включите переключатель Enable Pull to Refresh. Это автоматически добавит действие Refresh Database Request на жест обновления списка.
Прокрутка к началу или концу (Scroll To [Action])
С помощью этого действия можно прокрутить виджет до начала или конца списка.
Перед добавлением этого действия убедитесь, что у вас есть прокручиваемый виджет, такой как ListView, StaggeredView или GridView, с достаточным количеством элементов для обеспечения прокрутки.
Следуйте приведенным ниже шагам, чтобы добавить это действие к любому виджету.
- Выберите Виджет (например, FloatingActionButton), для которого вы хотите добавить действие.
- Перейдите в панель Actions (меню справа) и нажмите + Add Action.
- Найдите и выберите Scroll To (в разделе Widget/UI Interactions).
- Установите Scrollable Widget to Control в название прокручиваемого виджета (например, ListView), добавленного на вашу страницу.
- Установите Scroll To на Beginning (для прокрутки к началу) или End (для прокрутки к концу) списка.
- Укажите Duration в миллисекундах (например, 1000мс = 1 секунда). Это определяет, сколько времени потребуется для завершения анимации прокрутки. Совет: Если вы ожидаете, что список будет длинным, рассмотрите возможность установки более короткой длительности.