I want to make nested checkbox with dropdown. i will share the dropdown image here, kindly request to how manage this one
This is the actual UI i want to make,
Any one have any idea, please add it
2
You can use ExpansionTile.
ExpansionTile
return Scaffold( body: SingleChildScrollView( child: Column( children: [ for (int i = 0; i < 12; i++) ExpansionTile( title: Text("item"), leading: Checkbox( value: false, onChanged: (value) {}, ), children: [ for (int i = 0; i < 4; i++) CheckboxListTile( value: false, contentPadding: EdgeInsets.fromLTRB(24, 4, 4, 4), controlAffinity: ListTileControlAffinity.leading, onChanged: (v) {}, title: Text("sub item"), ) ], ) ], ), ), );
How to define the data model is the key to solving the problem
Refer to the following example, hope it will help you
import 'package:flutter/material.dart'; class MyWidget extends StatefulWidget { const MyWidget({super.key}); @override State<MyWidget> createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { List<PannelModel> _pannelList = [ PannelModel('dev_unit_test', false, [ {'dev_zone_test': false}, {'zone_A': false}, {'zone_B': false}, {'test_zone': false}, ]), PannelModel('dev_unit', false, [ {'dev_zone': false}, ]) ]; var _pannelSwich = ValueNotifier<List<PannelModel>>([]); @override void initState() { super.initState(); } @override void dispose() { _pannelSwich.dispose(); super.dispose(); } Widget _buildCheckBox( int modelIndex, MapEntry<int, Map<String, bool>> checkBoxMap) { var currenModel = _pannelSwich.value[modelIndex]; var title = currenModel.checkBoxList![checkBoxMap.key].keys.single; var isChecked = currenModel.checkBoxList![checkBoxMap.key].values.single; return Row( children: [ Checkbox( value: isChecked, onChanged: (val) { currenModel.checkBoxList![checkBoxMap.key] .update(title, (value) => !isChecked); setState(() {}); }), Text(title) ], ); } Widget _buildPannel(List<PannelModel> swichValues) { return Column( children: [ ...swichValues.asMap().entries.map((map) => ExpansionPanelList( elevation: 0, expandedHeaderPadding: EdgeInsets.all(0), expansionCallback: (_, __) { var pannelModel = _pannelSwich.value[map.key]; pannelModel.isOpen = !(pannelModel.isOpen ?? false); _pannelSwich.value[map.key] = pannelModel; setState(() {}); }, children: [ ExpansionPanel( headerBuilder: (context, _) { return ListTile( title: Text(swichValues[map.key].title ?? ''), ); }, canTapOnHeader: true, isExpanded: (_pannelSwich.value[map.key].isOpen ?? false), body: Column( children: [ ..._pannelSwich.value[map.key].checkBoxList! .asMap() .entries .map((checkBoxMap) => _buildCheckBox(map.key, checkBoxMap)) ], )) ], )) ], ); } @override Widget build(BuildContext context) { if (_pannelSwich.value.isEmpty) _pannelSwich.value = [..._pannelList]; return Scaffold( body: Center( child: SingleChildScrollView( child: Column( children: [ ValueListenableBuilder( valueListenable: _pannelSwich, builder: (context, swichValues, _) { return _buildPannel(swichValues); }) ], ))), ); } } class PannelModel { String? title; bool? isOpen; List<Map<String, bool>>? checkBoxList; PannelModel(this.title, this.isOpen, this.checkBoxList); }
Click here to cancel reply.
2
Answers
You can use
ExpansionTile
.How to define the data model is the key to solving the problem
Refer to the following example, hope it will help you