DropdownButtonFormField is not resetting first time - flutter

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

reset dropdown menu flutter

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"))
],
),
);
}
}

RenderCustomMultiChildLayoutBox object was given an infinite size during layout. How do i fix this?

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,

How do I call a data from a selected dropdown menu to a seperate class?

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!;
});
},
),
],
),
),
],
),
),
),
],
),
),
);
}
}

In Flutter Unable to change the state of DropDown Menu in ListView

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)],
),
),
],
),
);
}
}

onPressed create multiple instances of CheckboxListTile in Flutter

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);
});
},
),
],
);
}
}