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

Пример данных с сайта http://locationsng-api.herokuapp.com/api/v1/lgas выглядит так:

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

Начиная

$ flutter create multi_level_dropdown
$ cd multi_level_dropdown

Внутри папки lib создайте новый файл с именем repository.dart. Этот файл будет действовать как локальный источник данных. На всякий случай, если вы предпочитаете выполнять вызовы к конечной точке API, указанной выше, вы можете поменять местами метод getAll () (который мы еще не создали). Возьмите весь JSON, возвращенный из http://locationsng-api.herokuapp.com/api/v1/lgas, да, FAT JSON, и сохраните его как Dart Список. Также создайте три метода с именами getAll (), getStates () и getLocalByState (состояние строки) для получения всех данных, списка состояний и списка местные советы для данного штата соответственно. См. Сокращенную версию ниже

Модель данных

Перед реализацией функций давайте создадим класс для представления каждого из элементов JSON состояния. Это необязательно. Это мои предпочтения, мне нравится манипулировать состояниями как объектами, а не картами. И когда вы выбрали этот маршрут, вам не нужно вводить его самостоятельно, вы можете использовать этот инструмент JSON to Dart. Возьмите любой из элементов состояния из JSON и вставьте его в этот инструмент, затем нажмите кнопку Создать дротик. Проверьте сгенерированный код и внесите необходимые изменения. Вот мой код и сохраните его как state_model.dart

Простой класс с двумя фабричными методами toJson () и fromJSON (). Оба делают то, что подразумевают их имена: конвертируют в JSON, который мы сохранили из конечной точки API, и из него.

Итак, вернемся к файлу repository.dart, мы должны реализовать ожидающие методы.

Первая строка импортирует класс StateModel, поэтому мы можем использовать метод fromJson ().

getAll () просто возвращает список «FAT», содержащий карты состояний. Метод getStates () просто преобразует каждую карту состояний в объект StateModel, а затем преобразует коллекцию в список состояний. Результатом вызова этого метода будет:

['Adamawa', 'Akwa Ibom', 'Edo',...]

getLocalByState (String state) принимает аргумент состояния и возвращает список его местных советов. Первая функция map () преобразует каждую карту состояний в объект StateModel, функция where () фильтрует коллекцию по заданному состоянию, следующая функция карты преобразует ее только в «lgas» (собственность местного совета, которая в данном случае является списком). На этом этапе результатом является Список коллекции, мы используем expand ((i) = ›i), чтобы сгладить коллекцию, и, наконец, возвращает список местных советов. Результат для getLocalByState (‘Edo’) будет

['Akoko Edo', 'Estako East', ...]

Хорошо !, мы закончили с нашим источником данных. Создадим зависимый выпадающий список

Выпадающие виджеты

Откройте файл main.dart и замените его содержимое приведенным ниже кодом.

Затем создайте виджет с отслеживанием состояния Home

Добавьте несколько полей с исходными данными внутри класса HomeState

Repository repo = Repository();
List<String> _states = ["Choose a state"];
List<String> _lgas = ["Choose .."];
String _selectedState = "Choose a state";
String _selectedLGA = "Choose ..";

_states будет содержать список состояний из метода getStates (), _lgas будет содержать данные из getLocalsBy State (состояние), _selectedState и _selectedLGA представляют текущий элемент для каждого раскрывающегося меню.

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

_states = List.from (_states) .. addAll (repo.getStates ()) добавляет начальное значение _states в repo.getStates ()

Далее сделаем выпадающие списки. Flutter имеет виджет DropdownButton со свойством items, которое принимает список DropdownMenuItem. Итак, внутренний метод сборки включает следующее

Мы добавили некоторые отступы в контейнер и дочерний виджет Column со списком дочерних элементов DropdownButton. Первое свойство выпадающих элементов приведено ниже.

items: _states.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),

сопоставляет список _states и возвращает список DropdownMenuItem. Точно так же вторая отображает список _lgas и возвращает список DropdownMenuItem. Оба имеют значения по умолчанию, определенные в полях, определенных ранее в классе.

Следующие две области - это функции, вызываемые свойством onChange обоих DropdownButton: onChanged: (value) = ›_onSelectedState (value) и onChanged: (value) =› _onSelectedLGA (value)

Метод _onSelectedState устанавливает следующие значения для _selectedLGA, _lgas и _selectedState. Затем добавьте результат repo.getLocalByState (value) в список _lgas. Все это делается внутри метода setState ().

Метод _onSelectedLGA просто устанавливает текущее значение раскрывающейся кнопки для выбранного элемента.

Кажется, об этом. Сохраните изменения, запустите эмулятор и запустите приложение.

flutter run

Вы должны увидеть результат

Спасибо за уделенное время, ребята. Сообщите мне, если вы обнаружите ошибки, опечатки или более эффективные способы сделать это. Вы можете написать мне в Twitter @afegbuas

Репозиторий кода Github: https://github.com/shubie/Multi-Level-Dependent-Dropdown

Вы можете прочитать остальную часть Флаттер-четверг здесь: https://medium.com/@afegbua/flutter-thursday-series-9564d04e63a7