Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Android SDK
Code

Google Flutter с нуля: Сетки, списки и источники данных

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Google Flutter From Scratch.
Google Flutter From Scratch: Building Apps With Widgets
Google Flutter From Scratch: Animating Widgets

Russian (Pусский) translation by Ellen Nelson (you can also view the original English article)

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

Движок Flutter предлагает несколько виджетов, которые вы можете эффективно использовать для создания и отображения таких списков, при минимальном написании кода. В этом уроке, я покажу вам как использовать их с локальными и удалёнными источниками данных.

1. Отображение непрокручиваемых списков

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

Для создания списка в вашем приложении на Flutter, вы можете создать класс List, который предлагается языком программирования Dart. После создания списка, вы можете использовать его метод add(), для добавления в него любого количества пунктов. Следующий код показывает как создать список, содержащий три виджета RaisedButton:

Заметьте, что у каждого пункта в списке есть пустой, связанный с ним, обработчик событий onPressed, потому что без него данный пункт будет неактивным.

Теперь, когда список готов, чтобы отобразить его, вы можете назначить его непосредственно на свойство children виджета Column. Однако обычно, вам захочется определить где на экране будут располагаться элементы списка. Так как виджет Column является плавающим, вы можете управлять расположением его элементов, а также его положением по основной оси и оси пересечения, используя свойства mainAxisAlignment и crossAxisAlignment. По умолчанию, основная ось виджета Column — это вертикальная ось, а ось пересечения — горизонтальная ось.

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

Вот как теперь будет выглядеть column:

App displaying column with three buttons

Важно отметить, что во время выполнения возникнет ошибка, если виджету Column не удастся вместить все свои дочерние компоненты. Например, если в вашем списке более десятка виджетов RaisedButton вместо трёх, вы увидите сообщение об ошибке, которое выглядит вот так:

App displaying overflow error

2. Отображение простого прокручиваемого списка

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

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

Вот как вы можете быстро создать список, используя оператор [], который сейчас содержит только несколько строк:

Чтобы преобразовать список строк выше в список виджетов  RaisedButton, вы можете использовать методы map() и toList(). С помощью метода map(), вы можете использовать каждую строку для генерирования нового виджета RaisedButton. А с помощью метода toList(), вы можете преобразовать объекты Iterable, возвращаемые методом map() в объект List. Следующий код показывает как:

Для полноты картины, код выше, также показывает вам, как создать обработчик события onPressed, который использует методы canLaunch() и launch(), предлагаемые пакетом url_launcher для открытия веб-сайта, который выбрал пользователь в браузере по умолчанию.

Когда ваш список будет готов, вы можете передать его в свойство children виджета ListView для его отображения.

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

App displaying a scrollable list

3. Создание сетки

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

В следующем коде для создания виджета GridView, который отображает по два элемента в строку, используется конструктор GridView.count():

Вот как выглядит сетки:

App displaying a grid of buttons

4. Отображение больших списков

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

Вместо этого, вы должны использовать функцию IndexedWidgetBuilder, которая позволяет вам генерировать виджеты только когда пользователю нужно их увидеть. Таким образом виджеты генерируются «лениво», когда пользователь прокручивает ваш виджет ListView.

Весьма маловероятно, что у вас будет большое количество данных, определяемых прямо в вашем приложении. Обычно, вы получаете эти данные с удалённого сервера. Таким образом, чтобы дать вам реальный пример, давайте покажу вам как получить 100 вопросов с Stack Overflow, используя Stack Exchange API и отображением их по требованию.

Начнём с создания подкласса класса StatefulWidget, который будет действовать как контейнер для вашего виджета ListView и переопределять его метод createState().

Класс MyState, упомянутый в коде выше пока не существует, поэтому создаём его и перезапишем его метод build().

Далее, добавляем объект List как переменную этого класса. Вы будете использовать его для хранения вопросов, которые загружаются с Stack Overflow. Дополнительно, добавляем конечную точку в качестве другой переменной.

Если вы не хотите, чтобы пользователь нажал кнопку для загрузки вопросов, я рекомендую загружать их автоматически, при инициализации виджета. Соответственно, переопределяем метод initState() и вызываем новый асинхронный метод loadData().

Для загрузки вопросов, в методе loadData(), вы можете использовать функцию get() из http пакета от Dart. API конечной точки возвращает JSON документ, который вы можете спарсить, используя функцию json.decode(), доступную в пакете convert от Dart'а. В следующем коде показано как:

Как только документ JSON был сконвертирован в объект Map, вы можете использовать значения, связанные с ключами своих items, для инициализации переменной questions. Однако, переменная, является частью состояния виджета. Таким образом, вам надо убедиться, что вы обновили её только в методе setState(). Вот так:

А теперь вы можете создать новый виджет ListView с помощью конструктора ListView.builder(), который ожидает функция IndexedWidgetBuilder и item.count в качестве аргумента. Пока что, количество элементов — это не что иное, как размер списка questions. Соответственно, добавляем следующий код в метод build() класса MyState:

В функции сборщика, всё, что вам надо сделать — это создать маленькое дерево виджетов для отображения различных деталей о каждом вопросе, который вы загружаете. Пакет Flutter'а material предлагает очень полезный виджет, называемый ListTile, который позволяет быстро создать такое дерево придерживаясь правил Material Design.

Следующий код показывает вам, как отобразить заголовок и автора вопросов, используя свойства ваджета ListTile: title и subtitle:

И последнее, создаём новый виджет Scaffold, назначаем виджет ListView на его свойство body, и возвращаем в методе build(), таким образом его можно использовать с виджетом MaterialApp. Дополнительно, вы можете добавить виджет AppBar к виджету Scaffold.

Вот так будет выглядеть приложение после загрузки вопросов:

App displaying Stack Overflow data

Заключение

Теперь вы знаете, как работать со списками в приложении Flutter. В этом уроке, вы узнали не только как создавать списки и сетки, которые поддерживают большие источники данных, но и то, как создать в их каждый элемент интерактивно. Чтобы узнать больше о списках в Flutter, вы можете обратиться к официальной документации.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.