[Flutter/dart] Implement an event when tapping CheckboxListTile
Overview
CheckboxListTile is useful when you want to arrange strings and checkboxes in a horizontal row.
However, be careful if you want to implement an event such as moving to another page when you tap a string.
class MyHomePageState extends State<MyHomePage> {
List<int> list=List.generate(5, (index) => index);
List<bool> values=List.generate(5, (index) => false);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: list.map((e) =>
CheckboxListTile( //this!
value: values[e],
title: Text(
"${e}",
style: TextStyle(
fontSize: 18
),
),
onChanged: (value){
values[e]=value;
setState(() {});
}
)
).toList(),
)
)
);
}
}
Problem
CheckboxListTile has a property called onChanged that defines what happens when a checkbox is changed. The operation of changing the display of the check box is implemented here.
However, as mentioned earlier, be careful if you want to add an event (apart from changing the check value) when you tap CheckboxListTile.
In the first place, onTap is not defined in CheckboxListTile, and even if you wrap it with GesutureDetector, the onChanged event will run when you tap it.
Solution
Let's implement it by ourselves.
Assign Checkbox to trailing of ListTile.
In the case of ListTile, the onTap of entire and ontap of trailing (onChanged) are recognized separately.
class MyCheckboxListTile extends StatefulWidget{
Widget leading;
Widget title;
Function onTap;
Function(bool) onCheckChanged;
MyCheckboxListTile({this.leading, this.title, this.onTap, this.onCheckChanged});
@override
State<StatefulWidget> createState() {
return MyCheckboxListTileState();
}
}
class MyCheckboxListTileState extends State<MyCheckboxListTile>{
bool value=false;
@override
Widget build(BuildContext context) {
return ListTile(
leading: widget.leading,
title: widget.title,
trailing: Checkbox(
value: value,
onChanged: (value){
this.value=value;
widget.onCheckChanged(value);
setState(() {});
},
),
onTap: widget.onTap,
);
}
}
class MyPage extends StatelessWidget{
List<int> list=List.generate(5, (index) => index);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: list.map((e) =>
MyCheckboxListTile( //use here!
title: Text(
"${e}",
style: TextStyle(
fontSize: 18
),
),
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context)=>SomePage()
)
);
},
onCheckChanged: (value){},
)
).toList()
)
)
);
}
}
Since each tile is a Stateful Widget, you only need to rebuild the corresponding tile at the checking.
Colnclusion
If you want to implement onTap separately from onChanged, use ListTile and implement it by yourself.
Recent Posts
See AllWhat want to do I want to create an input form using TextField. For example, if the input content is a monetary amount, I would like to...
What want to do There is a variable that remain unchanged once the initial value is determined. However, it cannot be determined yet when...
What want to do As the title suggests. Place two widgets in one line on the screen One in the center of the screen and the other on the...
Comments