Flutter Multilevel Drop Down Tutorial
Flutter DropdownButton is a very important component of flutter app development, no app can be complete without using flutter dropdown. In this tutorial, we will focus on multilevel Dropdown which means, there will be a hierarchy of Dropdowns or you can say a parent-child relationship of Dropdown.
Flutter multilevel dropdown useful when user will choose a value from Dropdown A on the basis of selection Dropdown B will change its values. These values can be static or can come from a database or an API.
In this tutorial I am taking example of State and District relation. On the selection of State from dropdown, child will show District list. As the State will change District will also change as per selection.
Here is the code example of Flutter DropdownButton. This whole project is based on 4 different classes, as we are following best code practice so we categories our code in classes, as per need.
Class 1- slate_model.dart (which is a Model)
class StateModel {
String state;
List<String> districts;
StateModel({this.state, this.districts});
StateModel.fromJson(Map<String, dynamic> json) {
state = json['state'];
districts = json['districts'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['state'] = this.state;
data['districts'] = this.districts;
return data;
}
}
Class 2 – repostitory.dart (I have added only 2 json elements, whole json you can get from attached code)
import 'package:multi_dropdown/state_model.dart';
class Repository {
List<Map> getAll() => _india;
getLocalByState(String state) => _india
.map((map) => StateModel.fromJson(map))
.where((item) => item.state == state)
.map((item) => item.districts)
.expand((i) => i)
.toList();
List<String> getStates() => _india
.map((map) => StateModel.fromJson(map))
.map((item) => item.state)
.toList();
List _india = [
{
"state": "Andhra Pradesh",
"districts": [
"Anantapur",
"Chittoor",
"East Godavari",
"Guntur",
"Krishna",
"Kurnool",
"Nellore",
"Prakasam",
"Srikakulam",
"Visakhapatnam",
"Vizianagaram",
"West Godavari",
"YSR Kadapa"
]
},
{
"state": "Arunachal Pradesh",
"districts": [
"Tawang",
"West Kameng",
"East Kameng",
"Papum Pare",
"Kurung Kumey",
"Kra Daadi",
"Lower Subansiri",
"Upper Subansiri",
"West Siang",
"East Siang",
"Siang",
"Upper Siang",
"Lower Siang",
"Lower Dibang Valley",
"Dibang Valley",
"Anjaw",
"Lohit",
"Namsai",
"Changlang",
"Tirap",
"Longding"
]
},
];
}
Class 3- home_screen.dart
import 'package:flutter/material.dart';
import 'package:multi_dropdown/repository.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
Repository repo = Repository();
List<String> _states = ["Choose a state"];
List<String> _districts = ["Choose .."];
String _selectedState = "Choose a state";
String _selectedDistrict = "Choose ..";
@override
void initState() {
_states = List.from(_states)..addAll(repo.getStates());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Multi Dropdown Example"),
elevation: 0.1,
),
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 50, vertical: 30),
child: Column(
children: <Widget>[
DropdownButton<String>(
isExpanded: true,
items: _states.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
onChanged: (value) => _onSelectedState(value),
value: _selectedState,
),
DropdownButton<String>(
isExpanded: true,
items: _districts.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
// onChanged: (value) => print(value),
onChanged: (value) => _onSelectedDistrict(value),
value: _selectedDistrict,
),
],
),
),
),
);
}
void _onSelectedState(String value) {
setState(() {
_selectedDistrict = "Choose ..";
_districts = ["Choose .."];
_selectedState = value;
_districts = List.from(_districts)..addAll(repo.getLocalByState(value));
});
}
void _onSelectedDistrict(String value) {
setState(() => _selectedDistrict = value);
}
}
Class 4 – main.dart
import 'package:flutter/material.dart';
import 'package:multi_dropdown/home_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
If you have any query feel free to ask. Also check out the bottom navigation series and custom textfield and many others..
Download full code.
Thanks for reading.