I have this custom dropDown button and I want to get two values when I select one value from the list.
Here is the custom dropdown button
Widget customJsonDropDown(List? jsonList, String? value, void onChange(val)) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9),
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 5),
child: SizedBox(
//width: 80,
height: 50,
child: DropdownButton<String>(
hint: const Text('Select unit'),
value: value,
onChanged: (val) {
onChange(val);
},
items: jsonList?.map((item) {
return DropdownMenuItem(
value: item['conversion'].toString(),
child: Text(item['name']),
);
}).toList(),
underline: Container(),
isExpanded: true,
))));
}
here is the Json List
{
"Length": [
{
"name": "Meter",
"conversion": 1.0,
"base_unit": true
},
{
"name": "Millimeter",
"conversion": 1000.0
},
{
"name": "Centimeter",
"conversion": 100.0
}
]
}
as you guys can see that I am returning a String value from ['conversion'] and I am using ['name'] from jsonList to display the names. this works fine and I get the ['conversion'] values in return but what I want more is to store the Selected name in a variable as well. for example if I select Meter from dropdown button, it returns the conversion value on onChanged but I want to capture and assign the selected name as well to a variable.
So how can I do that and is it even possible? appreciate any help
CodePudding user response:
You can use any type for a DropdownButton
, not only String
. You can use your own model class types as well.
In your case since the value set is in a JSON, use <Map<String, dynamic>>
as the type of both DropdownButton
and DropdownMenuItem
. This way the value will be a Map
of the selected item so you can easily get both name
and conversion
.
This is a minimalistic example which you can try and adjust it to your needs:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(8.0),
child: MyDropdown(),
)),
),
);
}
}
class MyDropdown extends StatefulWidget {
const MyDropdown({Key? key}) : super(key: key);
@override
State<MyDropdown> createState() => MyDropdownState();
}
class MyDropdownState extends State<MyDropdown> {
Map<String, dynamic>? _selected;
final _json = {
'Length': [
{'name': 'Meter', 'conversion': 1.0, 'base_unit': true},
{'name': 'Millimeter', 'conversion': 1000.0},
{'name': 'Centimeter', 'conversion': 100.0}
]
};
@override
Widget build(BuildContext context) {
return DropdownButton<Map<String, dynamic>>(
value: _selected,
onChanged: (selected) => setState(() {
debugPrint(
'Selected name: ${selected?['name']}, conversion: ${selected?['conversion']}');
_selected = selected;
}),
items: _json['Length']
?.map((Map<String, dynamic> item) =>
DropdownMenuItem<Map<String, dynamic>>(
value: item,
child: Text(item['name']),
))
.toList());
}
}
CodePudding user response:
Try this:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class Unit {
final String name;
final double conversion;
final bool baseUnit;
const Unit(
{required this.name, required this.conversion, this.baseUnit = false});
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(8.0),
child: MyDropdown(),
)),
),
);
}
}
class MyDropdown extends StatefulWidget {
const MyDropdown({Key? key}) : super(key: key);
@override
State<MyDropdown> createState() => MyDropdownState();
}
class MyDropdownState extends State<MyDropdown> {
Unit? _selected;
final _units = const <Unit>[
Unit(name: 'Meter', conversion: 1.0, baseUnit: true),
Unit(name: 'Millimeter', conversion: 1000.0),
Unit(name: 'Centimeter', conversion: 100)
];
@override
Widget build(BuildContext context) {
return DropdownButton<Unit>(
value: _selected,
onChanged: (selected) => setState(() {
debugPrint(
'Selected name: ${selected?.name}}, conversion: ${selected?.conversion}');
_selected = selected;
}),
items: _units
.map((Unit unit) => DropdownMenuItem<Unit>(
value: unit,
child: Text(unit.name),
))
.toList());
}
}