Flutter CheckBox - flutter

I'm a new Flutter programmer, and I want to know how I can use a CheckBox on my App. The CheckBox doesn't need to return anything, is only a way to the user know the ingredients that they have picked up.
Thanks for everything.

A sample below might help :
bool _afternoonOutdoor = false;
String caption_afternoon_outdoor = 'Afternoon Outdoor';
void _afternoonOutdoorChanged(bool value) => setState(() => _afternoonOutdoor = value);
.
.
.
Widget checkBoxTitleAfternoonOutdoor() {
return Container(
width:230,
child: new CheckboxListTile(
value: _afternoonOutdoor,
onChanged: _afternoonOutdoorChanged,
//title: new Text('Afternoon Outdoor'),
//title: new Text('${_remoteConfig.getString('caption_afternoon_outdoor')}'),
title: new Text(caption_afternoon_outdoor),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.blue));
}
This produces the following result :

import 'package:flutter/material.dart';
import '../Models/meal.dart';
class Checkbox extends StatefulWidget {
#override
_CheckboxState createState() => _CheckboxState();
}
class _CheckboxState extends State<Checkbox> {
bool isCheck = false;
List<Meal> meal;
#override
Widget build(BuildContext context) {
return ListView(
padding: EdgeInsets.all(8.0),
children: meal
.map(
(meal) => CheckboxListTile(
title: Text(meal.ingredientes),
value: isCheck,
onChanged: (val) {
setState(() {
isCheck = val;
});
},
),
)
.toList(),
);
}
}

Related

How can I only check one checkbox at time?

How can I select/check only one checkbox to be checked at time?
And below is my code
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Checkbox(
checkColor: Colors.white,
value: isChecked,
onChanged: (bool value) {
setState(() {
isChecked = value;
// ignore: unnecessary_statements
passData(certId);
});
},
),
],
)),
Option1 - Using a map to maintain the state
Create a map:
final Map<int, bool> _state = {};
then, check if the value for that index is true/false:
return ListView.builder(itemBuilder: (context, index) {
return CheckboxListTile(
value: _state[index] ?? false,
onChanged: (value) {
setState(() {
_state[index] = value!;
});
},
title: Text(_data[index].text),
);
});
Option 2 - using a model:
class CheckBoxModel {
bool isChecked = false;
String text = "";
CheckBoxModel({required this.isChecked, required this.text});
}
and then, generate a List of 30 widgets:
final _data = List.generate(
30, (index) => CheckBoxModel(isChecked: false, text: "Item $index"));
Now, use a ListView.builder and based on the index, to update the corresponding value:
class Testing extends StatefulWidget {
const Testing({Key? key}) : super(key: key);
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
#override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index) {
return CheckboxListTile(
value: _data[index].isChecked,
onChanged: (value) {
setState(() {
_data[index].isChecked = value!;
});
},
title: Text(_data[index].text),
);
});
}
}
See also
Expansion tile trailing icon updates all in list on interaction with one tile. How can I only change the icon for the expanded tile?

Flutter: DropdownButton SetState not functional

i have a DropDownButton, which is filled from an SQLite DB which is ok for my app for now. But after choosing an entry, the DropDownButton didnt show the choosen entry, just the hint. To check my entry i try to fill a textfield also with the choosen entry, but this isnt changed too. Here is my code for the DropDownButton:
List<DropdownMenuItem<String>> teamList;
DropdownMenuItem selectedTeam;
DropdownButton(
hint: Text("Choose"),
value: selectedTeam,
onChanged: (value) {
setState(() {
_teamController.text = value.name;
selectedTeam = value;
});
},
items: teamList,
),
actually i fill my teamList with a codesnippet inside the initstate:
super.initState();
teamList = [];
db.getData().then((listMap) {
listMap.map((map) {
print(map.toString());
return getDropDownWidget(map);
}).forEach((dropDownMenuItem) {
teamList.add(dropDownMenuItem);
});
setState(() {});
});
and with this:
DropdownMenuItem<String> getDropDownWidget(Map<String, dynamic> map) {
return DropdownMenuItem<String>(
value: map['team'],
child: Text(map['team']),
);
}
in my dbhelper-file i have this code:
Future<List<Map<String, dynamic>>> getData() async {
var dbClient = await db;
return await dbClient.rawQuery('SELECT team FROM teamTable');
}
Hey Thomas Check out this example :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SampleApp(),
debugShowCheckedModeBanner: false,
);
}
}
class SampleApp extends StatefulWidget {
#override
_SampleAppState createState() => _SampleAppState();
}
class _SampleAppState extends State<SampleApp> {
List<String> teamList = ['Sample', 'Sample2', 'Sample3', 'Sample4'];
String selectedTeam;
TextEditingController _teamController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: Container(
child: Column(
children: <Widget>[
TextFormField(
controller: _teamController,
),
new DropdownButton<String>(
items: teamList.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
value: selectedTeam,
hint: Text('Choose'),
onChanged: (value) {
setState(() {
_teamController.text = value;
selectedTeam = value;
print('This is the selected value: $selectedTeam');
});
},
),
],
)));
}
}
Let me know if it works.

How do I change it such that the change is instant?

import 'package:flutter/material.dart';
class RandomPage extends StatefulWidget {
#override
_RandomScreenState createState() => _RandomScreenState();
}
class _RandomScreenState extends State {
String _selectedValue = 'Select';
bool appear = false;
Widget FirstDropDownButton() {
return Container(
child: DropdownButton <String> (
value: _selectedValue,
icon: Icon(Icons.arrow_drop_down),
underline: Container(
height: 1.5,
color: Colors.blueGrey,
),
onChanged: (String newValue) {
setState(() {
_selectedValue = newValue;
});},
items: <String> ['Select','One'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);}).toList(),
)
);
}
Widget FirstFlatButton() {
return FlatButton(
child: Text("Next"),
onPressed: () {
if (_selectedValue == 'Select') {
print("Cannot be NULL");
appear = false;
}
else if (_selectedValue == 'One')
appear = true;
});
}
Widget getWidget() {
if (appear == true) {
return Column(
children: <Widget>[
Text("Hello")
],
);
}
else
return Column(
children: <Widget>[
Text("Bye")
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget> [
FirstDropDownButton(),
FirstFlatButton(),
getWidget(),
],
)
);
}
}
Hi this is a simpler version of the code of mine.
If I choose 'one' from the dropdownbutton the hello text should appear but it doesnt, only when I go ahead and change the value of the dropdownbutton again then will it reflect the change.
How do I make it such that when I select 'one' such that text hello appears immediately and when i select 'select' the text bye appears and hello disappears at the click of the flatbutton without toggling the options again for the change to be reflected?
i have taken the liberty to modify your code a bit, and made it more general.
For live demo check: codepen
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: RandomPage(),
),
);
}
class RandomPage extends StatefulWidget {
#override
_RandomScreenState createState() => _RandomScreenState();
}
class _RandomScreenState extends State {
int _selectedValue = 0;
bool appear = false;
List<String> values = ['Select', 'One', 'Two', 'Three'];
Widget FirstDropDownButton() {
return Container(
child: DropdownButton<String>(
value: values[_selectedValue],
icon: Icon(Icons.arrow_drop_down),
underline: Container(
height: 1.5,
color: Colors.blueGrey,
),
onChanged: (String newValue) {
setState(() {
_selectedValue = values.indexWhere((element) => element == newValue);
});
changeFlag();
},
items: values.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
));
}
void changeFlag() {
if (values[_selectedValue] == 'One') {
setState(() {
appear = true;
});
} else {
setState(() {
appear = false;
});
}
}
Widget FirstFlatButton() {
return FlatButton(
child: Text("Next"),
onPressed: () {
setState(() {
_selectedValue = (_selectedValue + 1) % (values.length);
});
changeFlag();
});
}
Widget getWidget() {
if (appear == true) {
return Column(
children: <Widget>[Text("Hello")],
);
} else
return Column(
children: <Widget>[Text("Bye")],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("StackOverflow")),
body: Column(
children: <Widget>[
FirstDropDownButton(),
FirstFlatButton(),
getWidget(),
],
));
}
}
Update: Now that I re-read the question,
I figured that you wanted to show either the value Hello or Bye depending upon the value on dropdown, when the user clicked Next button,
but i am sure you got the idea whatsoever,
just remove the setState on the flatbutton and changeFlag in the dropdown and you'll be fine.

How to resolve flutter dropdownButtonFormField dynamic selection checking for dropdownButton's value

I am trying to ask the user to select the type of item in the first dropdown and then select from its corresponding available colours in the second dropdown. However, when after I have selected a colour (i.e. white) and now want to switch to another item that does not have this colour, an error is thrown:
"There should be exactly one item with [DropdownButton]'s value: white. \nEither zero or 2 or more
[DropdownMenuItem]s were detected with the same value"
Please help, I have already tried to setState at various places to update the values but this error still occurs.
The following is my code snippet:
StreamBuilder<QuerySnapshot>(
stream: mainItemsSnapshots,
builder: (context, snapshot) {
if (snapshot.hasError) return Text("Error");
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
{
List<DropdownMenuItem> dropdownMenuItems =
snapshot.data.documents
.map((DocumentSnapshot mainItem) {
return new DropdownMenuItem<String>(
value: mainItem.documentID,
child: Text(mainItem.documentID),
);
}).toList();
return DropdownButtonFormField<String>(
items: dropdownMenuItems,
onChanged: (String value) {
if (value != tempMainItemType) {
setState(() {
tempMainItemType = value;
tempItemColorsList.clear();
tempItemColorsList = [];
tempMainItemColor = null;
});
}
if (tempItemColorsList.isEmpty && value != null) {
tempItemColorsList = snapshot.data.documents
.where((element) => element.documentID == value)
.first
.data["colors"]
.keys
.map((color) => color.toString())
.toList()
.cast<String>();
}
setState((){});
},
onSaved: (String value) {
_order.mainItemType = value;
},
value: tempMainItemType,
);
}
}
},
),
// Main color
if (tempItemColorsList?.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: spacingGeneral),
child: textFieldLabel(context, "Main color"),
),
if (tempItemColorsList?.isNotEmpty)
DropdownButtonFormField(
items: tempItemColorsList.map((String color) {
return new DropdownMenuItem<String>(
value: color,
child: Text(color),
);
}).toList(),
onSaved: (String value) {
_order.mainColor = value;
},
value: tempMainItemColor,
onChanged: (String value) {
setState(() {
tempMainItemColor = value;
});
},
),
This maybe too late, but you can create a Map<String, List<String>> where the keys are the items of the first dropdown list, and the value will be the items of second dropdown list.
Here, I created a state that stores the selected item of the first dropdown list. Then I used it to map the items of the second dropdown list.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SampleDD(),
);
}
}
class SampleDD extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DoubleDropdown(
items: <String, List<String>>{
'dark colors': ['black', 'gray', 'brown'],
'light colors': ['white', 'yellow', 'green'],
},
onChangedFirst: (val) => print('Selected first: $val'),
onChangedSecond: (val) => print('Selected second: $val'),
),
),
);
}
}
class DoubleDropdown extends StatefulWidget {
DoubleDropdown({
#required this.items,
#required this.onChangedFirst,
#required this.onChangedSecond,
});
final Map<String, List<String>> items;
final ValueChanged<String> onChangedFirst;
final ValueChanged<String> onChangedSecond;
#override
_DoubleDropdownState createState() => _DoubleDropdownState();
}
class _DoubleDropdownState extends State<DoubleDropdown> {
String selectedKey;
#override
void initState() {
super.initState();
selectedKey = widget.items.keys.first;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
_buildFirstDropdown(),
_buildSecondDowndown(),
],
);
}
Widget _buildFirstDropdown() => DropdownButtonFormField<String>(
items: widget.items.keys.map((e) {
return DropdownMenuItem<String>(
child: Text(e),
value: e,
);
}).toList(),
onChanged: (val) {
setState(() => selectedKey = val);
widget.onChangedFirst(val);
},
value: selectedKey,
);
Widget _buildSecondDowndown() => DropdownButtonFormField<String>(
items: widget.items[selectedKey].map((e) {
return DropdownMenuItem<String>(
child: Text(e),
value: e,
);
}).toList(),
onChanged: widget.onChangedSecond,
value: widget.items[selectedKey].first,
);
}

How can I handle a list of checkboxes dynamically created in flutter?

Using flutter, I am trying to build a list of values with some text and a customized checkbox next to it. Tapping anywhere on the text or checkbox should show the enabled state and tapping again should disable it. I am unsure how to handle the state of each checkbox separately. I tried using CheckBoxListTile too but I am not sure how I can achieve what I want. Can someone provide any examples?
Here's some sample code for CheckboxListTile. You can find more examples in the gallery.
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
#override
DemoState createState() => new DemoState();
}
class DemoState extends State<Demo> {
Map<String, bool> values = {
'foo': true,
'bar': false,
};
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('CheckboxListTile demo')),
body: new ListView(
children: values.keys.map((String key) {
return new CheckboxListTile(
title: new Text(key),
value: values[key],
onChanged: (bool value) {
setState(() {
values[key] = value;
});
},
);
}).toList(),
),
);
}
}
void main() {
runApp(new MaterialApp(home: new Demo(), debugShowCheckedModeBanner: false));
}
I think it will work as you want. It also stores all selected checkbox value(s) into a List variable. so you please simply put this code in main.dart file and execute to check how it works.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Multi-Select & Unselect Checkbox in Flutter'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List _selecteCategorys = List();
Map<String, dynamic> _categories = {
"responseCode": "1",
"responseText": "List categories.",
"responseBody": [
{"category_id": "5", "category_name": "Barber"},
{"category_id": "3", "category_name": "Carpanter"},
{"category_id": "7", "category_name": "Cook"}
],
"responseTotalResult":
3 // Total result is 3 here becasue we have 3 categories in responseBody.
};
void _onCategorySelected(bool selected, category_id) {
if (selected == true) {
setState(() {
_selecteCategorys.add(category_id);
});
} else {
setState(() {
_selecteCategorys.remove(category_id);
});
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: ListView.builder(
itemCount: _categories['responseTotalResult'],
itemBuilder: (BuildContext context, int index) {
return CheckboxListTile(
value: _selecteCategorys
.contains(_categories['responseBody'][index]['category_id']),
onChanged: (bool selected) {
_onCategorySelected(selected,
_categories['responseBody'][index]['category_id']);
},
title: Text(_categories['responseBody'][index]['category_name']),
);
}),
);
}
}
use List contains returns bool.
here is example
List<int> selectedList = [];
List<Widget> mList; //you can't add equal
createMenuWidget(Course courses) {
for (int b = 0; b < courses.length; b++) {
Map cmap = courses[b];
mList.add(CheckboxListTile(
onChanged: (bool value){
setState(() {
if(value){
selectedList.add(cmap[course_id]);
}else{
selectedList.remove(cmap[course_id]);
}
});
},
value: selectedList.contains(cmap[course_id]),
title: new Text(cmap[course_name]),
));
}
}
The simple Way to Do this with Dynamic List of Data with CheckBox.
List<String>data= ["Mathew","Deon","Sara","Yeu"];
List<String> userChecked = [];
ListView.builder(
itemCount: data.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(
data[i])
trailing:Checkbox(
value: userChecked.contains(data[i]),
onChanged: (val) {
_onSelected(val, data[i]);
},
)
//you can use checkboxlistTile too
);
})
// now we write the functionality to check and uncheck it!!
void _onSelected(bool selected, String dataName) {
if (selected == true) {
setState(() {
userChecked.add(dataName);
});
} else {
setState(() {
userChecked.remove(dataName);
});
}
}
And Its Done !!...
Enjoy Fluttering...
Give a thumbs up as it will work for you !! :P
Please use package grouped_buttons.
It support both checkbox and radio.
https://pub.dartlang.org/packages/grouped_buttons
CheckboxGroup(
labels: <String>[
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
disabled: [
"Wednesday",
"Friday"
],
onChange: (bool isChecked, String label, int index) => print("isChecked: $isChecked label: $label index: $index"),
onSelected: (List<String> checked) => print("checked: ${checked.toString()}"),
),
and full example of usage in here https://github.com/akshathjain/grouped_buttons/blob/master/example/lib/main.dart
and author's logic to implement
https://github.com/akshathjain/grouped_buttons/blob/master/lib/src/checkbox_group.dart
Basically, author use two List of Strings to control selected and unselect
void onChanged(bool isChecked, int i){
bool isAlreadyContained = _selected.contains(widget.labels.elementAt(i));
if(mounted){
setState(() {
if(!isChecked && isAlreadyContained){
_selected.remove(widget.labels.elementAt(i));
}else if(isChecked && !isAlreadyContained){
_selected.add(widget.labels.elementAt(i));
}
if(widget.onChange != null) widget.onChange(isChecked, widget.labels.elementAt(i), i);
if(widget.onSelected != null) widget.onSelected(_selected);
});
}
}
Screenshot (Null safe)
Code:
class _MyPageState extends State<MyPage> {
final Map<String, bool> _map = {};
int _count = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => setState(() => _map.addEntries([MapEntry('Checkbox #${++_count}', false)])),
),
body: ListView(
children: _map.keys
.map(
(key) => CheckboxListTile(
value: _map[key],
onChanged: (value) => setState(() => _map[key] = value!),
subtitle: Text(key),
),
)
.toList(),
),
);
}
}
Use chekboxListTile
Here is the sample code
#override
Widget build(BuildContext context) {
return Center(
child: CheckboxListTile(
title: Text('Check me'),
);
}
By the way, You can also add checkbox in ListView in Flutter. Apps sample is given below-
Main.dart
import 'package:flutter/material.dart';
import 'checkbox_in_listview_task-7.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue,
),
home: CheckBoxInListview(),
);
}
}
checkbox_in_listview_task.dart
import 'package:flutter/material.dart';
class CheckBoxInListview extends StatefulWidget {
#override
_CheckBoxInListviewState createState() => _CheckBoxInListviewState();
}
class _CheckBoxInListviewState extends State<CheckBoxInListview> {
bool _isChecked = true;
List<String> _texts = [
"InduceSmile.com," "Flutter.io",
"google.com",
"youtube.com",
"yahoo.com",
"gmail.com"
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("CheckBox in ListView Example"),
),
body: ListView(
padding: EdgeInsets.all(8.0),
children: _texts.map((text) => CheckboxListTile(
title: Text(text),
value: _isChecked,
onChanged: (val) {
setState(() {
_isChecked = val;
});
},
)).toList(),
),
);
}
}
And here is the output
here how you can do it
import 'package:flutter/material.dart';
class RegisterFragments extends StatefulWidget {
RegisterFragments({Key key, this.step}) : super(key: key);
final int step;
_RegisterFragmentsState createState() => _RegisterFragmentsState();
}
class _RegisterFragmentsState extends State<RegisterFragments> {
Map<String, bool> values = {"abc": false, "def": true, "ghi": false};
List<String> _do = ['One', 'Two', 'Free', 'Four'];
String _dropdownValue = 'One';
#override
Widget build(BuildContext context) {
switch (widget.step) {
case 0:
return buildDo();
break;
case 1:
return Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: values.length,
itemBuilder: (BuildContext context, int index) {
switch (widget.step) {
case 0:
return buildDo();
break;
case 1:
return buildService(context, index);
break;
default:
return Container();
break;
}
},
),
);
break;
default:
return Container();
break;
}
}
Widget buildService(BuildContext context, int index) {
String _key = values.keys.elementAt(index);
return Container(
child: Card(
child: CheckboxListTile(
title: Text(_key),
onChanged: (bool value) {
setState(() {
values[_key] = value;
});
},
value: values[_key],
),
),
);
}
Widget buildDo() {
return DropdownButton<String>(
isExpanded: true,
hint: Text("Service"),
items: _do.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
this._dropdownValue = newValue;
});
},
value: _dropdownValue,
);
}
}
In case you are using the CheckBoxGroup or anything similar AND are inside a slider, do not forget to put it in a StatefulBuilder:
return StatefulBuilder(// StatefulBuilder
builder: (context, setState) {
return CheckboxGroup(
orientation: GroupedButtonsOrientation.HORIZONTAL,
margin: const EdgeInsets.only(left: 12.0),
onSelected: (List selected) => setState(() {
_checked = selected;
}),
labels: teamWorkoutDays,
checked: _checked,
itemBuilder: (Checkbox cb, Text txt, int i) {
return Column(
children: <Widget>[
Icon(Icons.polymer),
cb,
txt,
],
);
},
);
});