I'm new to flutter so I'm not sure how to go about this. I want to be able to add another instance of the same CheckboxListTile when a user presses a button right below the most recent CheckboxListTile.
The code for how it currently is is below.
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
CheckboxListTile(
title: TextField(
autocorrect: true,
),
value: checkBoxValue,
secondary: Icon(Icons.assignment),
onChanged: (bool newValue) {
setState(() {
checkBoxValue = newValue;
});
}
),
],
The code of an example of how I would want the app to appear after a user presses is below.
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
CheckboxListTile(
title: TextField(
autocorrect: true,
),
value: checkBoxValue,
secondary: Icon(Icons.assignment),
onChanged: (bool newValue) {
setState(() {
checkBoxValue = newValue;
});
}
),
CheckboxListTile(
title: TextField(
autocorrect: true,
),
value: checkBoxValue,
secondary: Icon(Icons.assignment),
onChanged: (bool newValue) {
setState(() {
checkBoxValue = newValue;
});
}
),
],
Thanks in advance!
Generating widgets in a ListView is by adding List<Widget> in its children. Simply put, it roughly looks similar to.
ListView(
children: <Widget>[widgetA, widgetA, widgetC]);
What you need to do is to manually add widgets in List<Widget>. You can create a List<Widget> _checkboxList and create a function that returns a CheckboxListTile widget.
CheckboxListTile _checkboxListTile(){
return CheckboxListTile(
title: TextField(
autocorrect: true,
),
value: checkBoxValue,
secondary: Icon(Icons.assignment),
onChanged: (bool newValue) {
setState(() {
checkBoxValue = newValue;
});
}
);
}
and on your button, call _checkboxList.add(_checkboxListTile()); to add it on List<Widget> _checkboxList
RaisedButton(
onPressed: () {
setState(() {
_checkboxList.add(_checkboxListTile());
});
},
child: Text('Add checkbox'),
),
To display List _checkboxList on your screen:
Widget build(BuildContext context) {
return ListView(children: _checkboxList);
}
Let me know if this helps.
One way you could do it is by using a ListView.builder like this..
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
List<bool> checkBoxesCheckedStates = [false];
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: checkBoxesCheckedStates.length,
itemBuilder: (BuildContext context, int index){
return CheckboxListTile(
title: TextField(
autocorrect: true,
),
value: checkBoxesCheckedStates[index],
secondary: Icon(Icons.assignment),
onChanged: (bool newValue) {
setState(() {
checkBoxesCheckedStates[index] = newValue;
});
},
);
},
),
),
RaisedButton(
child: Text('Add'),
onPressed: (){
setState(() {
checkBoxesCheckedStates.add(false);
});
},
),
],
);
}
}
Related
how to reset dropdonw to defult value after press button ?
i am trying to press button to reset dropdownmune to its defualt
class drawarScreen extends StatelessWidget {
const drawarScreen({super.key});
#override
Widget build(BuildContext context) {
List<String> list = <String>['One', 'Two', 'Three', 'Four'];
String? dropdownValue;
return Scaffold(
body: Column(children:[
DropdownButton<String>(
hint: Text('moammed'),
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? value) {
// This is called when the user selects an item.
setstate({
dropdownValue = value!;
});
},
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
},
ElevatedButton(
onPress:(){
setstate({
dropdownValue='';
});
},child: Text("reste");
)
]);
}
}
i am trying to press button to reset dropdownmune to its defualt
resat dropdown menu in flutter
You need to put null value instead of empty string
setstate({
dropdownValue = null ;
});
If you like to have other than null, put it there.
And make sure to have StatefulWidget and variables outside the build method.
Full widget
class drawarScreen extends StatefulWidget {
const drawarScreen({super.key});
#override
State<drawarScreen> createState() => _drawarScreenState();
}
class _drawarScreenState extends State<drawarScreen> {
List<String> list = <String>['One', 'Two', 'Three', 'Four'];
String? dropdownValue;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
DropdownButton<String>(
hint: Text('moammed'),
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? value) {
setState(() {
dropdownValue = value;
});
},
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
ElevatedButton(
onPressed: () {
setState(() {
dropdownValue = null;
});
},
child: Text("Reset"))
],
),
);
}
}
I ran this code and it returns an error : RenderCustomMultiChildLayoutBox object was given an infinite size during layout. I couldn't figure out which widget has the error. This is my code.
import 'package:flutter/material.dart';
import '../mediaquery.dart';
class DropdownTextfield extends StatefulWidget {
#override
_DropdownTextfieldState createState() => _DropdownTextfieldState();
}
class _DropdownTextfieldState extends State<DropdownTextfield> {
var properties = [
'kg',
'yd',
'm',
];
String dropdownvalue = 'kg';
String _property1 = '';
String _property2 = '';
String _property3 = '';
bool _isOptionSelected = false;
TextEditingController quantitycontroller = TextEditingController();
var selectedOption;
TextEditingController textfieldValue = TextEditingController();
final List<String> options = [];
#override
void initState() {
super.initState();
selectedOption = options.isNotEmpty ? options[0] : null;
}
#override
Widget build(BuildContext context) {
final screenHeight = ScreenInfo.screenHeight(context);
final screenWidth = ScreenInfo.screenWidth(context);
return Scaffold(
body: SingleChildScrollView(
child: SizedBox(
height: screenHeight * 0.8,
child: Column(
children: [
TextField(
onChanged: (value) {
setState(() {
textfieldValue.text = value;
});
},
),
DropdownButton<String>(
value: selectedOption,
onChanged: (value) {
setState(() {
selectedOption = value!;
_isOptionSelected = true;
});
},
hint: const Text('Input from Text Field Above'),
items: options.map((option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
),
TextButton(
onPressed: () {
setState(() {
options.add(textfieldValue.text);
});
},
child: Text("Add Option"),
),
Visibility(
visible: _isOptionSelected,
child: Column(
children: <Widget>[
Row(
children: [
TextField(
controller: quantitycontroller,
decoration: InputDecoration(labelText: "Quantity"),
onChanged: (value) {
setState(() {
_property1 = value;
});
},
),
const SizedBox(width: 10,),
DropdownButton(
value: dropdownvalue,
items: properties.map((properties) {
return DropdownMenuItem(
value: properties,
child: Text(properties),
);
}).toList(),
onChanged: (String? newValue){
setState(() {
dropdownvalue = newValue!;
});
},
)
],
),
],
),
),
],
),
),
),
);
}
}
I tried to use a Container and a SizedBox with fixed height as shown above but it doesn't seem to do anything. I also tried wrapping the children of the Row widget with Expanded and Flexible but those too doesn't seem to fix it. How can I fix this?
TextField is trying to get infinite width and Row widget providing it. Wrap your TextFieldwith Expanded widget to get available space.
Expanded(
child: TextField(
controller: quantitycontroller,
I have a goal to change the state of the checkbox when clicking on the adjacent widget. I tried to create a stateful function but unfortunately my code doesn't work.
Here is the function -
void _changeFlagCheckBox(bool? value){
setState(() {
MyCheckBoxCountry.isChecked = value!;
});
}
Inkwell - when you click on it, it should change the state of myCheckBoxCountry.
child: ListView.builder(
itemCount: city.length,
shrinkWrap: true
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
print(city[index]);
_changeFlagCheckBox;
},
child: Container(
margin: const EdgeInsets.only(top: 15),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
Row(
children:[
SizeBox(width: 10,),
Text(city[index], style: TextStyle(color: ConfigColor.white, fontWeight: FontWeight.w500, fontSize: 15),)
],
),
MyCheckBoxCountry()
],
)
),
);
},
),
myCheckBoxCountry -
class MyCheckBoxCountry extends StatefulWidget {
static bool isChecked = false;
#override
_MyCheckBoxState createState() => _MyCheckBoxState();
}
class _MyCheckBoxState extends State<MyCheckBoxCountry> {
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
unselectedWidgetColor: ConfigColor.grey,
),
child: Checkbox(
activeColor: ConfigColor.green,
checkColor: ConfigColor.background,
value: MyCheckBoxCountry.isChecked,
shape: CircleBorder(),
onChanged: (bool? value) {
setState(() {
MyCheckBoxCountry.isChecked = value!;
});
},
),
);
}
}
First of all you're not sending any value in your _changeFlagCheckBox function in your Inkwell so how is it supposed to change :
InkWell(
onTap: () {
print(city[index]);
_changeFlagCheckBox; //should be _changeFlagCheckBox(!MyCheckBoxCountry.isChecked)
},
but to understand why didn't you get an error like that, well that's because you made the bool value nullable in your _changeFlagCheckBox function:
void _changeFlagCheckBox(bool? value){ //should be (bool value)
setState(() {
MyCheckBoxCountry.isChecked = value!;
});
}
Though even then you are not using your isChecked value in your MyCheckBoxCountry class anywhere :
Checkbox(
activeColor: ConfigColor.green,
checkColor: ConfigColor.background,
value: MyCheckBoxCountry.isChecked,
shape: CircleBorder(),
onChanged: (bool? value) {
setState(() {
MyCheckBoxCountry.isChecked = value!; //should be the other way around
});
},
),
Should have been :
setState(() {
value = MyCheckBoxCountry.isChecked;
});
I guess since it is an another stateful widget class, It does not recognize the setState. Calling child widget from parent widget would solve the problem.
I want to change the Elevated button color when I press the radio buttons. 1.button -> red, 2.button -> yellow, 3.button -> green. In the Elevated.stylefrom if condition did not work. Just ternary condition works but it is only for one condition. I want to add 3 conditions. I hope it was clear.
Or do I need to create a model for this?
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:task_shopping_app/const/const.dart';
import 'package:task_shopping_app/screens/city_input_screen.dart';
import 'package:task_shopping_app/screens/weather.dart';
class RadioButton extends StatefulWidget {
#override
_RadioButtonState createState() => _RadioButtonState();
}
class _RadioButtonState extends State<RadioButton> {
int selectedValue = 0;
final enteredCityInfo = TextEditingController();
String name = '';
// if selectedValue and group value matches then radio button will be selected.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
Radio<int>(
value: 1,
groupValue: selectedValue,
onChanged: (value) => setState(() {
selectedValue = value!;
print(selectedValue);
})),
Radio<int>(
value: 2,
groupValue: selectedValue,
onChanged: (value) => setState(() {
selectedValue = value!;
print(selectedValue);
})),
Radio<int>(
value: 3,
groupValue: selectedValue,
onChanged: (value) => setState(() {
selectedValue = value!;
print(selectedValue);
})),
],
),
Padding(
padding: const EdgeInsets.all(25.0),
child: TextField(
controller: enteredCityInfo,
),
),
ElevatedButton(
onPressed: () {
setState(() {
name = enteredCityInfo.text;
//Here we want to see user entry for the text field area in the debug console.
print(name);
// Get.to(() => WeatherScreen());
});
},
child: Text('Create'),
style: ElevatedButton.styleFrom(
primary: selectedValue == 1 ? Colors.red : Colors.yellow,
),
)
],
),
);
}
}
enter code here
I think you can create a function to convert the value into Colors
Color valueToColor(int value) {
switch (value) {
case 1:
return Colors.red;
case 2:
return Colors.yellow;
case 3:
return Colors.green;
default:
/// return whatever you like to deal with some exceptional case
}
}
And make the style parameter of ElevatedButton like following
style: ElevatedButton.styleFrom(
primary: valueToColor(selectedValue),
),
Use like this for multiple conditions:
primary:(selectedValue == 1) ? Colors.red : (selectedValue == 2)?
Colors.yellow:Colors.green,
I want to reset DropdownButtonFormField. I mange to reset it by setting it's value null and using globalkey as following code.
Here, problem is that i need to click twice to reset it.
Note: I know using DropdownButton, we can reset more easily but my question is why DropdownButtonFormField is not resetting when i click first time.
After Update:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
String abc;
FocusNode _node = FocusNode();
GlobalKey<FormState> _key = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Form(
key: _key,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Focus(
focusNode: _node,
onFocusChange: (bool focus) {
setState(() {});
},
child: Listener(
onPointerDown: (_) {
FocusScope.of(context).requestFocus(_node);
},
child: DropdownButtonFormField(
hint: Text('select value'),
value: abc,
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
abc = newValue;
});
},
),
),
),
Text("value is $abc"),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
abc = null;
_key.currentState.reset();
});
},
tooltip: 'Reset',
child: Icon(Icons.clear),
)),
);
}
}
you may need to make manual Focus
you need to give the global key to form as well
FocusNode _node = FocusNode();
...
Focus(
focusNode: _node,
onFocusChange: (bool focus) {
setState(() {});
},
child: Listener(
onPointerDown: (_) {
FocusScope.of(context).requestFocus(_node);
},
child: DropdownButtonFormField(
iconSize: 50,
onChanged: (s) {
setState(() {
abc = s;
});
},
hint: Text(
'Select Text',
),
items: [
DropdownMenuItem(value: '1', child: Text('A')),
DropdownMenuItem(value: '2', child: Text('B')),
DropdownMenuItem(value: '3', child: Text('C')),
DropdownMenuItem(value: '4', child: Text('D')),
],
),
),
),
...
FloatingActionButton(
onPressed: () {
setState(() {
print("hello");
abc = null;
_key.currentState.reset();
});
// _flyIronMan();
},
child: Icon(Icons.add),
),