Unable to uncheck the check Box - flutter

I am using CheckboxListTile in for check box. It works good if selected : false. If selected is true then unable to un check it.
final checkBox = CheckboxListTile(
contentPadding: EdgeInsets.all(0),
title: Text("Remember Me", style: TextStyle(fontSize: 15.0)),
selected: checkBoxState,
value: checkBoxState,
checkColor: Colors.white,
activeColor: Colors.grey,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (newValue) {
setState(() {
checkBoxState = newValue;
});
},
);
This is the code what I am using.
Thanks in Advance,

I don't know how you are using checkBox, but this code works perfectly fine.
class _MyWidgetState extends State<MyWidget> {
bool checkBoxState = true;
#override
Widget build(BuildContext context) {
return CheckboxListTile(
contentPadding: EdgeInsets.all(0),
title: Text("Remember Me", style: TextStyle(fontSize: 15.0)),
selected: checkBoxState,
value: checkBoxState,
checkColor: Colors.white,
activeColor: Colors.grey,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (newValue) {
setState(() {
checkBoxState = newValue;
});
},
);
}
}

You should use like below. You need to set bool true false reversing inside setState like checkBoxState = !checkBoxState;. And declare bool globally. bool checkBoxState = false;
bool checkBoxState = false;
final checkBox = CheckboxListTile(
contentPadding: EdgeInsets.all(0),
title: Text("Remember Me", style: TextStyle(fontSize: 15.0)),
selected: checkBoxState,
value: checkBoxState,
checkColor: Colors.white,
activeColor: Colors.grey,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (newValue) {
setState(() {
checkBoxState = !checkBoxState;
});
},
)

Related

Flutter Dropdown list expanding instead of scrolling

So im making my first Dropdown but when i have a lot of Strings it expands upwards, is there a way to compact the list and make it scrollable or am i using the wrong Widget?
class _DropdownBehaivorButton extends StatefulWidget {
const _DropdownBehaivorButton({super.key});
#override
State<_DropdownBehaivorButton> createState() => _DropdownBehaivorButtonState();
}
class _DropdownBehaivorButtonState extends State<_DropdownBehaivorButton> {
String dropdownvalue = 'Agresivo';
var tipos = [
'Agresivo',
'Tranquilo',
'Travieso',
'Docil',
'Travieso',
'Travieso',
'Travieso'
];
#override
Widget build(BuildContext context) {
return
DropdownButtonHideUnderline(
child: DropdownButton(
borderRadius: BorderRadius.circular(25),
isExpanded: true,
iconEnabledColor: Color(0xff525252),
dropdownColor: Colors.white,
style: _textStyle(),
value: dropdownvalue,
icon: const Icon(Icons.keyboard_arrow_down),
items: tipos.map((String items) {
return DropdownMenuItem(
value: items,
child: Center(child: Text(items)),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
dropdownvalue = newValue!;
});
},
),
);
}
TextStyle _textStyle() => TextStyle(
fontSize: 18,color: Color.fromARGB(123, 82, 82, 82),fontWeight: FontWeight.w400) ;}
I was expecting a compact dropdown list like this
DropdownButton(
menuMaxHeight: 100, // this line
hint: const Text(
"Please select Child / Patient"),
underline: const SizedBox(),
isExpanded: true,
iconEnabledColor: Colors.blue[800],
dropdownColor: Colors.grey[100],
style: TextStyle(
letterSpacing: 2,
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.grey[800]),
value: patientName,
items: patients.map((patient) {
return DropdownMenuItem(
value: patient,
child: Text(patient.childName),
);
}).toList(),
onChanged: (value) {
setState(() {
patientName = value;
debugPrint(patientName!
.toJson()
.toString());
});
}),
try changing the menu max height
Try to add dropdownMaxHeight: 200
Here you will find what you need https://pub.dev/packages/dropdown_button2

how to make the value of DropDown Button updated?

so i aim to use a dropDownButton if already i have selected an option i find it selected ( the value is saved in DataBase) and of course it can be modified else if i didn't choose any option i choose . so this is using the attribute value : value: box.read("optioSaved") ?? dropDownValue, but here if the user has already choose a value he can't modified it
how can i do ?
this is the full code :
child: DropdownButton<String>(
icon: const Icon(Icons.keyboard_arrow_down),
isExpanded: true,
style: const TextStyle(
color: Colors.black,
fontSize: 17,
fontFamily: 'SFProRegular',
),
underline: Container(
height: 1,
color: Colors.black,
),
onChanged: (String? newValue) {
setState(() {
dropDownValue = newValue;
});
},
items: <String>[
"option1",
"option 2",
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
value: box.read("optioSaved") ?? dropDownValue,
hint: const Text("choose"),
),
assign box.read("optioSaved") to dropDownValue in initState and then just value: dropDownValue

How to make checkbox ListTile with rounded box using Getx in Flutter

I am relatively new to Flutter development and I want to implement checkbox as shown in the screenshot attached using GetX flutter. Also I want the borders of my check-boxes to be round.
screenshot
You can make a CheckBox round by using the shape field and the CircleBorder class or RoundedRectangleBorder (if you want them to have rounded corners):
Checkbox(
checkColor: Colors.white,
value: isChecked,
shape: CircleBorder(),
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
);
Result:
Or:
Checkbox(
checkColor: Colors.white,
value: isChecked,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))),
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
);
Result:
To use GetX I think you should provide some code or example to explain what do you mean and what you want to exactly achieve, otherwise the best advice is probably to read the documentation and check some example.
As you've mentioned in the screenshot.
You can achieve it with GetX as following:
Create a variable for keep tracking the checked value
final Rxn<int> selected = Rxn<int>();
Now you have to implement the UI with Obx widget to listen for the changes of observing variable 'selected'
Obx(
() => Column(
children: [
CheckboxListTile(
title: const Text('This is the title 1'),
subtitle: const Text('This is the subtitle with ID 1'),
checkColor: Colors.white,
activeColor: Colors.blueGrey,
controlAffinity: ListTileControlAffinity.leading,
checkboxShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
value: selected.value == 1,
onChanged: (val) {
val ?? true ? selected.value = 1 : selected.value = null;
},
),
CheckboxListTile(
title: const Text('This is the title 2'),
subtitle: const Text('This is the subtitle with ID 2'),
checkColor: Colors.white,
activeColor: Colors.blueGrey,
controlAffinity: ListTileControlAffinity.leading,
checkboxShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
value: selected.value == 2,
onChanged: (val) {
val ?? true ? selected.value = 2 : selected.value = null;
},
),
],
),
))
The following will be the output:

Updating parent form from child using Radio

I am developing a form with 11 multiple choice questions.
Ive created a statefull widget which takes the question and displays this along with 3 radio buttons as below.
Each question needs to update different property in a model defined within the parent widget.
for example:
RadioQuestionWidget("What colour is the sky?", model.ColourOfSky),
RadioQuestionWidget("What colour is the grass?", model.ColourOfGrass)
Below is my RadioQuestionWidget
import 'package:flutter/material.dart';
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question}) : super(key: key);
final String question;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
class _RadioQuestionWidgetState extends State<RadioQuestionWidget> {
String question;
var _radioValue;
#override
void initState() {
super.initState();
question = widget.question;
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
question,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Radio(
value: "Yes",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'Yes',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "No",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'No',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "Three",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.red,
focusColor: Colors.black,
),
new Text(
'Not applicable',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
],
),
),
],
),
);
}
}
First of all, define one function in your parent widget with required arguments i.e your question number and answer.
void _updateProperty(int que_num, String ans) {
//update property according to your question number and ans
}
Now pass your function to child widget as the Constructor argument.
RadioQuestionWidget(question : "What colour is the sky?", updatePropertyHandler : _updateProperty)
Receive your function in child widget like below.
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question, this.updatePropertyHandler}) : super(key: key);
final String question;
final Function updatePropertyHandler;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
Now in your child widget while you answering the question, call _updateUi function as per your need.
Radio(
value: "Yes",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(questionNum, _radioValue);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
)
Firstly please mark the above answer as the correct one as i couldn't have got it working without the help of #Alpesh.
I had to slightly amend the answer in order to update the correct property of the model.
This in my parent widget:
RadioQuestionWidget(
question: 'Question 1',
updatePropertyHandler: (String ans) => {
setState(() {
_qc.speedForSpeedChaeckCompleted = ans;
})
},
),
and this is my RadioQuestionWidget:
import 'package:flutter/material.dart';
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question, this.updatePropertyHandler})
: super(key: key);
final String question;
final Function updatePropertyHandler;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
class _RadioQuestionWidgetState extends State<RadioQuestionWidget> {
String question;
var _groupValue;
Function(String) onCountChange;
#override
void initState() {
super.initState();
question = widget.question;
_groupValue = 'Not Applicable';
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
question,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Radio(
value: "Yes",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'Yes',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "No",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'No',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "Not Applicable",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.red,
focusColor: Colors.black,
),
new Text(
'Not applicable',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
],
),
),
],
),
);
}
}

Checkbox form validation

How can I validate a checkbox in a Flutter Form? Every other validation works fine, but the checkbox doesn't show an Error.
Here is my code:
FormField(
validator: (value) {
if (value == false) {
return 'Required.';
}
},
builder: (FormFieldState<dynamic> field) {
return CheckboxListTile(
value: checkboxValue,
onChanged: (val) {
if (checkboxValue == false) {
setState(() {
checkboxValue = true;
});
} else if (checkboxValue == true) {
setState(() {
checkboxValue = false;
});
}
},
title: new Text(
'I agree.',
style: TextStyle(fontSize: 14.0),
),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.green,
);
},
),
A cleaner solution to this problem is to make a class that extends FormField<bool>
Here is how I accomplished this:
class CheckboxFormField extends FormField<bool> {
CheckboxFormField(
{Widget title,
FormFieldSetter<bool> onSaved,
FormFieldValidator<bool> validator,
bool initialValue = false,
bool autovalidate = false})
: super(
onSaved: onSaved,
validator: validator,
initialValue: initialValue,
builder: (FormFieldState<bool> state) {
return CheckboxListTile(
dense: state.hasError,
title: title,
value: state.value,
onChanged: state.didChange,
subtitle: state.hasError
? Builder(
builder: (BuildContext context) => Text(
state.errorText,
style: TextStyle(color: Theme.of(context).errorColor),
),
)
: null,
controlAffinity: ListTileControlAffinity.leading,
);
});
}
in case if you want to put your checkbox directly in your Form widget tree you can use solution provided below with FormField widget. Instead of using ListTile I used rows and columns as my form was requiring different layout.
FormField<bool>(
builder: (state) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
Checkbox(
value: checkboxValue,
onChanged: (value) {
setState(() {
//save checkbox value to variable that store terms and notify form that state changed
checkboxValue = value;
state.didChange(value);
});
}),
Text('I accept terms'),
],
),
//display error in matching theme
Text(
state.errorText ?? '',
style: TextStyle(
color: Theme.of(context).errorColor,
),
)
],
);
},
//output from validation will be displayed in state.errorText (above)
validator: (value) {
if (!checkboxValue) {
return 'You need to accept terms';
} else {
return null;
}
},
),
You could try something like this :
CheckboxListTile(
value: checkboxValue,
onChanged: (val) {
setState(() => checkboxValue = val
},
subtitle: !checkboxValue
? Text(
'Required.',
style: TextStyle(color: Colors.red),
)
: null,
title: new Text(
'I agree.',
style: TextStyle(fontSize: 14.0),
),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.green,
);
The above answer is correct, however, if you want to display an error message that is more consistent with the default layout of a TextFormField widget error message, then wrap the Text widget in a Padding widget, and give it the hex colour #e53935.
Note: You may need to adjust the left padding to fit the CheckboxListTile widget is also wrapped in a Padding widget.
Check the code below:
bool _termsChecked = false;
CheckboxListTile(
activeColor: Theme.of(context).accentColor,
title: Text('I agree to'),
value: _termsChecked,
onChanged: (bool value) => setState(() => _termsChecked = value),
subtitle: !_termsChecked
? Padding(
padding: EdgeInsets.fromLTRB(12.0, 0, 0, 0),
child: Text('Required field', style: TextStyle(color: Color(0xFFe53935), fontSize: 12),),)
: null,
),