I'm trying to make dropdownbutton using Getx in flutter
However, it doesn't work.
Even if I choose a value, the value does not been selected.
class BecomePlayerPage2 extends GetView<BecomePlayerController> {
const BecomePlayerPage2 ({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Obx(
() => Scaffold(
body: Padding(
padding: EdgeInsets.all(20),
child:
DropdownButton<RxString>(
onChanged: (newValue){
controller.selected=newValue!;
},
value: controller.selected,
items: [
for(var value in controller.tierList)
DropdownMenuItem(
child: new Text(
value,
),
value: value.obs,
),
]
),
),
),
}
class BecomePlayerController extends GetxController {
final tierList=['first', 'second', 'third'].obs;
var selected = "first".obs;
}
This is my first day of studying Getx so it is so hard to match with basic widget.
What should I do?
Try replacing the onChange statement with
onChanged: (newValue) {
controller.selected.value = newValue.toString();
},
or by changing Dropdown button type from RXString to String
return Obx(
() => Scaffold(
body: Padding(
padding: const EdgeInsets.all(20),
child: DropdownButton<String>( // updated
onChanged: (newValue) {
controller.selected.value = newValue!; //updated
},
value: controller.selected.value, //updated
items: [
for (var value in controller.tierList)
DropdownMenuItem(
value: value,
child: Text(
value, //updated
),
),
]),
),
),
);
Use round brackets to update .obs and change RxString to String
authController.selected(newValue.toString());
onChanged: (newValue){
// controller.selected=newValue!;
controller.selected.value =newValue!;
},
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 just started learning flutter, I have programming knowledge before, but I am just getting used to the widget structure. What I want to do is add a button to the last element of the DropdownButton list and I used the DropdownMenuItem widget to do that. And I used Text as child and I put Button in the last element. The problem is, I can't give Text to the value property of the DropdownButton. That's why I'm getting an error because I've given a value that isn't in items [ ]. Is there any way I can get the value of the Text widget? Or can I do it another way? I hope I was explanatory.
code:
class _TodoPageState extends State<TodoPage> {
Text dropdownValue = Text('123'); // **FOR DEFAULT VALUE**
#override
Widget build(BuildContext context) {
return SafeArea(
child: Center(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyTabBar(),
Row(
children: [
Expanded(
child: Container(
margin: EdgeInsets.only(left: 3, top: 5),
child: Row(
children: [
Ink(
width: 152,
height: 45,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2),
borderRadius: BorderRadius.circular(10),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: dropdownValue, **// CANT SET THE DEFAULT VALUE**
isExpanded: true,
icon: Image.asset('assets/down-list-arrow.png'),
iconSize: 10,
elevation: 16,
onChanged: (newValue) {
setState(() {
dropdownValue = newValue!; **// CANT SET THE DEFAULT VALUE**
});
},
items: [
DropdownMenuItem(child: Text('123'), value: ''),
DropdownMenuItem(child: Text('123'), value: ''),
DropdownMenuItem(
child: TextButton(
child: Text('Create'),
onPressed: () {},
))
],
),
),
)
],
),
),
),
],
),
MyListView()
],
),
));
}
}
I found 2 ways: Assigning create on values or check new value before assigning on onChanged and using FocusNode.
Test Widget
class TodoPage extends StatefulWidget {
TodoPage({Key? key}) : super(key: key);
#override
_TodoPageState createState() => _TodoPageState();
}
class _TodoPageState extends State<TodoPage> {
late String selectedValue; // **FOR DEFAULT VALUE**
late String selectedValue2;
List<String> dropDownItemValue = ['123', '2', '4', 'Create'];
List<String> dropDownItemValue2 = ['xx', '2', '4'];
late final dropDownKey2;
final FocusNode dropDownFocus = FocusNode();
#override
void initState() {
super.initState();
///selected value must be contain at dropDownItemValue
selectedValue = dropDownItemValue[0];
selectedValue2 = dropDownItemValue2[0];
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.deepPurple,
body: Center(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
// MyTabBar(),
DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: selectedValue, // CANT SET THE DEFAULT VALUE**
isExpanded: true,
// icon: Image.asset('assets/down-list-arrow.png'),
iconSize: 10,
elevation: 16,
onChanged: (newValue) {
print(newValue);
setState(() {
selectedValue = newValue!; // SET THE DEFAULT VALUE**
});
},
/// dont assing same value on multiple widget
items: List.generate(
dropDownItemValue.length,
(index) => DropdownMenuItem(
child: Text('${dropDownItemValue[index]}'),
value: '${dropDownItemValue[index]}'),
),
),
),
SizedBox(
height: 100,
),
DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusNode: dropDownFocus,
value: selectedValue2, // CANT SET THE DEFAULT VALUE**
isExpanded: true,
// icon: Image.asset('assets/down-list-arrow.png'),
iconSize: 10,
elevation: 16,
onChanged: (newValue) {
print(newValue == null);
// if value doesnt contain just close the dropDown
if (newValue == null) {
dropDownFocus.unfocus();
} else
setState(() {
selectedValue2 = newValue; // SET THE DEFAULT VALUE**
});
},
/// dont assing same value on multiple widget
items: List.generate(
dropDownItemValue2.length + 1,
(index) => index < dropDownItemValue2.length
? DropdownMenuItem(
child: Text('${dropDownItemValue2[index]}'),
value: '${dropDownItemValue2[index]}')
: DropdownMenuItem(
child: TextButton(
child: Text('Create'),
onPressed: () {},
),
),
),
),
),
],
),
),
));
}
}
I am new to flutter, I can easily create a stateless widget and require value to be set when creating an object (#required this.value)
However, I am a bit lost on how to do it with a stateful widget.
When looking at the code below, I want to be able to get "hint" value from the object created, into the stateful widget constructor, and down to the drop-down menu. I hope this makes sense.
class MyDropdownButton extends StatefulWidget { MyDropdownButton({
this.hint, }); String hint; #override _MyDropdownButtonState createState() => _MyDropdownButtonState(); }
class _MyDropdownButtonState extends State<MyDropdownButton> { String dropdownValue; String hint;
#override Widget build(BuildContext context) {
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'TO',
style: TextStyle(color: kColourGreyText),
),
DropdownButton<String>(
value: dropdownValue != null ? dropdownValue : null,
hint: Text(hint),
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: kColourGreyText),
underline: Container(
height: 2,
color: kColorPrimary,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items:
accountNameList.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
); } }
You can access widget properties from a state directly. Try widget.hint
Found multiple problems with your code,
class MyDropdownButton extends StatefulWidget {
MyDropdownButton({#required this.hint}); // use #required for required parameters, like this one here
final String hint; // use final
#override
_MyDropdownButtonState createState() => _MyDropdownButtonState();
}
// below line you missed `<MyDropdownButton>` after `State`,
// I'd suggest using a recommended IDE with a recommended Flutter
// Extention to generate code samples
class _MyDropdownButtonState extends State<MyDropdownButton> {
String dropdownValue;
// I added below 3 lines to avoid the errors in this sample code
List<String> accountNameList = [];
Color kColorPrimary = Colors.blue;
Color kColourGreyText = Colors.grey;
#override
Widget build(BuildContext context) {
// You don't need `Expanded` here, just wrap it with `Row` only
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('TO', style: TextStyle(color: kColourGreyText)),
DropdownButton(
value: dropdownValue != null ? dropdownValue : null,
// when accessing parsed values in Statful,
// use widget.<variable name>
hint: Text(widget.hint),
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: kColourGreyText),
underline: Container(height: 2, color: kColorPrimary),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: accountNameList.map((String value) {
return DropdownMenuItem(value: value, child: Text(value));
}).toList(),
),
],
);
}
}
and again, I'd suggest using a recommended IDE with a recommended Flutter Extention to generate code samples
i have a DropDownButton which add category for my product. after added product DropDownButton display category which i choosed. I want to refresh or clear DropDownButton after adding product. Better to display hint text.
code:
child: StreamBuilder<List<Categories>>(
stream: categories,
builder: ((context, snapshot) {
if (!snapshot.hasData)
return CircularProgressIndicator();
return DropdownButton(
hint: Text('choose category'),
value: _currentCategory,
items: snapshot.data
.map((doc) => DropdownMenuItem(
child: Text(doc.categoryname),
value: doc,
))
.toList(),
onChanged: (selectedCategory) =>
setState(() {
_currentCategory = selectedCategory;
}),
);
})),
),
SizedBox(height: 15),
RaisedButton(
onPressed: () {
if (_formKeyProduct.currentState.validate()) {
ProductService().addProduct(
_nameproductController.text,
_priceproductController.text,
_currentCategory.categoryname.toString());
_formKeyProduct.currentState.reset();
_nameproductController.clear();
_priceproductController.clear();
}
},
child: Text('add product'),
Since the value you chose is _currentCategory using
setState(() {
_currentCategory = null;
}
)
should do the trick.
EDIT:
I see some downvotes on this. This answer was based on Flutter 1.22.6. If it doesn't work on Flutter 2 that is why.
This is a complete widget including a button to reset the dropdown value. It is based on provider package. The widget include a button to clear selection.
class MyDataDropDown extends StatelessWidget {
#override
Widget build(final BuildContext context) {
return Consumer<HomeModel>(
builder: (context, model, child) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(10)),
child: Row(
children: [
Expanded(
child: DropdownButton<SearchMyData>(
isExpanded: true,
value: model.currentMyData,
onChanged: (final SearchMyData? newValue) {
model.setCurrentMyData(newValue);
},
items: model.data.map<DropdownMenuItem<SearchMyData>>((SearchMyData value) {
return DropdownMenuItem<SearchMyData>(
value: value,
child: Text(MyDataDataUtils.getMyDataLabelDropDown(value), overflow: TextOverflow.ellipsis),
);
}).toList(),
// add extra sugar..
hint: const Text("Pick a data"),
icon: const Icon(Icons.arrow_drop_down),
underline: const SizedBox(),
),
),
IconButton( // clear dropdown button
onPressed: () => model.setCurrentMyData(null),
icon: Icon(Icons.clear))
],
),
);
},
);
}
}
Provider class
class HomeModel extends ChangeNotifier{
....
UnmodifiableListView<SearchTheme> get data => UnmodifiableListView([your data here]);
SearchMyData? _selectedMyData;
SearchMyData? get currentMyData => _selectedMyData;
setCurrentMyData(final SearchMyData? item) {
_selectedMyData = item;
notifyListeners();
}
}
Now you have a complete dropdown including clear selection button.
I'm trying to make it possible to edit a list of strings. The problem is, when I delete a list item via the IconButton, the TextField rebuilds but somehow still has the old value. With debugging I see, that my List of Strings are however updated correctly, meaning the deleted String is actually being deleted in my list.
This is my code:
class EditInfoItemDialog extends StatefulWidget {
#override
State<StatefulWidget> createState() => _EditInfoitemDialogState();
}
class _EditInfoitemDialogState extends State<EditInfoItemDialog> {
final _formKey = GlobalKey<FormState>();
List<String> values = ['A', 'B', 'C'];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[
...values.asMap().map((int index, String point) {
return MapEntry(index, Row(
children: [
Text(index.toString()),
Expanded(
child: TextFormField(
decoration: InputDecoration(hintText: 'Info'),
initialValue: values[index],
onChanged: (value) => setState(() {values[index] = value; }),
),
),
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
setState(() {
values.removeAt(index);
print(values);
});
},
)
]
));
}).values.toList(),
FlatButton(
child: Text('Add Bulletpoint'),
onPressed: () {
setState(() {
if (values == null) values = [];
values.add('');
});
},
)
],
),
),
);
}
Any Ideas?
You need to add a key to your TextFormField like this:
key: ObjectKey(values[index])
Here is an explanation and an example with the reason why you need to add a key in this case: What are Keys in the Stateless widgets class?
Key is something used by flutter engine at the step of recognizing
which widget in a list as changed
More info:
key property