@@ -1013,3 +1013,168 @@ List<Widget> indicators(imagesLength, currentIndex) {
10131013 });
10141014}
10151015```
1016+ ## Multiselect with Checkboxes
1017+ ``` dart
1018+ // main.dart
1019+ import 'package:flutter/material.dart';
1020+
1021+ void main() {
1022+ runApp(const MyApp());
1023+ }
1024+
1025+ class MyApp extends StatelessWidget {
1026+ const MyApp({Key? key}) : super(key: key);
1027+
1028+ @override
1029+ Widget build(BuildContext context) {
1030+ return MaterialApp(
1031+ debugShowCheckedModeBanner: false,
1032+ title: 'KindaCode.com',
1033+ theme: ThemeData(
1034+ // enable Material 3
1035+ useMaterial3: true,
1036+ primarySwatch: Colors.indigo,
1037+ ),
1038+ home: const HomePage(),
1039+ );
1040+ }
1041+ }
1042+
1043+ // Multi Select widget
1044+ // This widget is reusable
1045+ class MultiSelect extends StatefulWidget {
1046+ final List<String> items;
1047+ const MultiSelect({Key? key, required this.items}) : super(key: key);
1048+
1049+ @override
1050+ State<StatefulWidget> createState() => _MultiSelectState();
1051+ }
1052+
1053+ class _MultiSelectState extends State<MultiSelect> {
1054+ // this variable holds the selected items
1055+ final List<String> _selectedItems = [];
1056+
1057+ // This function is triggered when a checkbox is checked or unchecked
1058+ void _itemChange(String itemValue, bool isSelected) {
1059+ setState(() {
1060+ if (isSelected) {
1061+ _selectedItems.add(itemValue);
1062+ } else {
1063+ _selectedItems.remove(itemValue);
1064+ }
1065+ });
1066+ }
1067+
1068+ // this function is called when the Cancel button is pressed
1069+ void _cancel() {
1070+ Navigator.pop(context);
1071+ }
1072+
1073+ // this function is called when the Submit button is tapped
1074+ void _submit() {
1075+ Navigator.pop(context, _selectedItems);
1076+ }
1077+
1078+ @override
1079+ Widget build(BuildContext context) {
1080+ return AlertDialog(
1081+ title: const Text('Select Topics'),
1082+ content: SingleChildScrollView(
1083+ child: ListBody(
1084+ children: widget.items
1085+ .map((item) => CheckboxListTile(
1086+ value: _selectedItems.contains(item),
1087+ title: Text(item),
1088+ controlAffinity: ListTileControlAffinity.leading,
1089+ onChanged: (isChecked) => _itemChange(item, isChecked!),
1090+ ))
1091+ .toList(),
1092+ ),
1093+ ),
1094+ actions: [
1095+ TextButton(
1096+ onPressed: _cancel,
1097+ child: const Text('Cancel'),
1098+ ),
1099+ ElevatedButton(
1100+ onPressed: _submit,
1101+ child: const Text('Submit'),
1102+ ),
1103+ ],
1104+ );
1105+ }
1106+ }
1107+
1108+ // Implement a multi select on the Home screen
1109+ class HomePage extends StatefulWidget {
1110+ const HomePage({Key? key}) : super(key: key);
1111+
1112+ @override
1113+ State<HomePage> createState() => _HomePageState();
1114+ }
1115+
1116+ class _HomePageState extends State<HomePage> {
1117+ List<String> _selectedItems = [];
1118+
1119+ void _showMultiSelect() async {
1120+ // a list of selectable items
1121+ // these items can be hard-coded or dynamically fetched from a database/API
1122+ final List<String> items = [
1123+ 'Flutter',
1124+ 'Node.js',
1125+ 'React Native',
1126+ 'Java',
1127+ 'Docker',
1128+ 'MySQL'
1129+ ];
1130+
1131+ final List<String>? results = await showDialog(
1132+ context: context,
1133+ builder: (BuildContext context) {
1134+ return MultiSelect(items: items);
1135+ },
1136+ );
1137+
1138+ // Update UI
1139+ if (results != null) {
1140+ setState(() {
1141+ _selectedItems = results;
1142+ });
1143+ }
1144+ }
1145+
1146+ @override
1147+ Widget build(BuildContext context) {
1148+ return Scaffold(
1149+ appBar: AppBar(
1150+ title: const Text('Multi Select'),
1151+ ),
1152+ body: Padding(
1153+ padding: const EdgeInsets.all(20),
1154+ child: Column(
1155+ crossAxisAlignment: CrossAxisAlignment.start,
1156+ children: [
1157+ // use this button to open the multi-select dialog
1158+ ElevatedButton(
1159+ onPressed: _showMultiSelect,
1160+ child: const Text('Select Your Favorite Topics'),
1161+ ),
1162+ const Divider(
1163+ height: 30,
1164+ ),
1165+ // display selected items
1166+ Wrap(
1167+ children: _selectedItems
1168+ .map((e) => Chip(
1169+ label: Text(e),
1170+ ))
1171+ .toList(),
1172+ )
1173+ ],
1174+ ),
1175+ ),
1176+ );
1177+ }
1178+ }
1179+ ```
1180+
0 commit comments