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),
),
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,
Here is my code. I am trying to get the data from the TextField and the DropdownMenuItem value that are inputted and selected from the Visibility widget in the DropdownTextfield widget, but when I tried to call the dropdownValue it isn't defined. How can I pass the function or the value to my desired map to add it to Firebase?
class FakturPage extends StatefulWidget {
const FakturPage({Key? key}) : super(key: key);
static String id = 'fakturpage';
#override
State<FakturPage> createState() => _FakturPageState();
}
class _FakturPageState extends State<FakturPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
FirebaseFirestore.instance.collection('Faktur').add({
'Quantity': '$quantityController',
'Metric': '$dropdownValue', //this is where the error occurred
});
},
),
body: SingleChildScrollView(
child: Column(
children: [
DropdownTextfield(),
],
),
),
);
}
}
class DropdownTextfield extends StatefulWidget {
#override
_DropdownTextfieldState createState() => _DropdownTextfieldState();
}
class _DropdownTextfieldState extends State<DropdownTextfield> {
var properties = [
'kg',
'g',
'yd',
'buah',
];
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 Center(
child: Container(
height: screenHeight * 0.2,
width: screenWidth * 0.8,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
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: const Text("Add Option"),
),
Visibility(
visible: _isOptionSelected,
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Row(
children: [
Expanded(
child: TextField(
controller: quantitycontroller,
decoration:
const 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'm trying to change the state of DropDown using setState, value is changing but it is not reflecting on UI, it's only reflecting on the new widget when I'm adding a new Widget.
App Function
Initially, it's a blank screen
When I click on Add it will add dropdown menu & text field
Similarly, we can add many. Those widgets will be added to _mypets list
When I click on save I'm printing an array of lists
How can I change the state?
This is a Stateful Widget
Please help me to resolve this issue
class _MyPetNameState extends State<MyPetName> {
var locationArray = [];
var _myPets = List<Widget>();
String sampleData = 'Hello';
int _index = 1;
var dataForm;
String partnerName;
List<_dropListItem> _weekItems = [
_dropListItem(1, "Pet Type 1"),
_dropListItem(2, "Pet Type 2"),
_dropListItem(3, "Pet Type 3"),
_dropListItem(3, "Pet Type 4"),
];
List<DropdownMenuItem<_dropListItem>> _weekMenuItems;
_dropListItem _selectedWeekItem;
List<DropdownMenuItem<_dropListItem>> buildDropDownMenuItems(List listItems) {
List<DropdownMenuItem<_dropListItem>> items = List();
for (_dropListItem listItem in listItems) {
items.add(
DropdownMenuItem(
child: Text(listItem.name),
value: listItem,
),
);
}
return items;
}
void _addLocation() {
Map<String, String> _formData= {};
int keyValue = _index;
_myPets = List.from(_myPets)
..add(Column(
key: Key("${keyValue}"),
children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: DropdownButton<_dropListItem>(
value: _selectedWeekItem,
items: _weekMenuItems,
onChanged: (value) {
_formData['location'] = value.name;
setState(() {
_weekMenuItems = buildDropDownMenuItems(_weekItems);
_selectedWeekItem = value;
});
}),
),
Container(
child: TextFormField(
initialValue: '',
onChanged: (val) {
_formData['locationType'] = val;
setState(() {
sampleData = val;
});
},
),
),
],
));
setState(() => ++_index);
locationArray.add(_formData);
}
void _sub(int _deleteIndex){
setState(() {
_myPets = List.of(_myPets)..removeAt(_deleteIndex - 1);
--_index;
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
_weekMenuItems = buildDropDownMenuItems(_weekItems);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
print('');
print(locationArray);
setState(() {
dataForm = [];
});
},
child: Text('Save'),
),
appBar: AppBar(
title: Text('Add your pets'),
actions: <Widget>[
FlatButton(
child: Text('Add'),
onPressed: (){
_addLocation();
},
),
],
),
body: Column(
children: [
Expanded(
child: ListView(
children: _myPets,
),
),
],
),
);
}
}
class _dropListItem {
int value;
String name;
_dropListItem(this.value, this.name);
}
I have made some changes in your code
This may help you
class _MyPetNameState extends State<MyPetName> {
List<dynamic> radioval = [];
setSelectedRadio(int val, int idx) {
setState(() {
radioval[idx]["value"] = val;
});
}
Widget _radioui(int keyValue) {
return Column(
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
Radio(
value: 0,
groupValue: radioval[keyValue]["value"],
activeColor: Colors.green,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val, keyValue);
},
),
Radio(
value: 1,
groupValue: radioval[keyValue]["value"],
activeColor: Colors.blue,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val, keyValue);
},
),
],
)
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
radioval.add({"name": "pet1", "value": 0});
});
},
child: Icon(Icons.add),
),
appBar: AppBar(
title: Text('Add your pets'),
),
body: Column(
children: [
Expanded(
child: ListView(
children: [for (int i = 0; i < radioval.length; i++) _radioui(i)],
),
),
],
),
);
}
}
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);
});
},
),
],
);
}
}