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
CodePudding user response:
You can use 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"),
)
],
)
],
),
),
);
CodePudding user response:
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);
}