How to combine DropdownMenu and AppLocalization in Flutter within context?
You can copy paste run full code below
You can use package https://pub.dev/packages/equatable and extend Equatable
code snippet
import 'package:equatable/equatable.dart';
...
class KeyValueRecordType extends Equatable {
String key;
String value;
KeyValueRecordType({this.key, this.value});
@override
List<Object> get props => [key, value];
}
working demo
full code
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
class KeyValueRecordType extends Equatable {
String key;
String value;
KeyValueRecordType({this.key, this.value});
@override
List<Object> get props => [key, value];
}
class AddNewTrainingForm extends StatefulWidget {
@override
AddNewTrainingFormState createState() => AddNewTrainingFormState();
}
class AddNewTrainingFormState extends State<AddNewTrainingForm> {
KeyValueRecordType recordType;
@override
Widget build(BuildContext context) {
List<KeyValueRecordType> recordTypes = <KeyValueRecordType>[
KeyValueRecordType(key: "dressage", value: 'dressage'),
KeyValueRecordType(key: "cavaletti", value: 'cavaletti'),
KeyValueRecordType(key: "jumping", value: 'jumping'),
KeyValueRecordType(key: "hacking", value: 'hacking'),
KeyValueRecordType(key: "groundwork", value: 'groundwork'),
KeyValueRecordType(key: "competition", value: 'competition'),
KeyValueRecordType(key: "other", value: 'other'),
];
return SafeArea(
child: Scaffold(
body: Container(
child: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.white,
),
child: DropdownButton<KeyValueRecordType>(
value: recordType,
onChanged: (KeyValueRecordType value) {
setState(() {
recordType = value; //show selected value
});
},
items: recordTypes
.map<DropdownMenuItem<KeyValueRecordType>>(
(recordType) => new DropdownMenuItem<KeyValueRecordType>(
child: Text(recordType.value),
value: recordType,
))
.toList(),
),
),
)),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: AddNewTrainingForm(),
);
}
}
marhyno
Updated on December 24, 2022Comments
-
marhyno over 1 year
I am having trouble working with dropdown menu in flutter together with AppLocalization. I have implemented automatic localization based on user selected language in phone settings. It works good until I want to implement also dropdown menu with localised values. When I render dropdown menu it works but after I select value a get an error like this Flutter: There should be exactly one item with [DropdownButton]'s value, Please note I need appLocalization in the KeyValueRecords list,
import 'package:MyHorse.sk/app_localizations.dart'; class AddNewTrainingFormState extends State<AddNewTrainingForm> { KeyValueRecordType recordType; @override Widget build(BuildContext context) { List<KeyValueRecordType> recordTypes = <KeyValueRecordType>[ KeyValueRecordType( key: "dressage", value: AppLocalizations.of(context).translate('dressage')), KeyValueRecordType( key: "cavaletti", value: AppLocalizations.of(context).translate('cavaletti')), KeyValueRecordType( key: "jumping", value: AppLocalizations.of(context).translate('jumping')), KeyValueRecordType( key: "hacking", value: AppLocalizations.of(context).translate('hacking')), KeyValueRecordType( key: "groundwork", value: AppLocalizations.of(context).translate('groundwork')), KeyValueRecordType( key: "competition", value: AppLocalizations.of(context).translate('competition')), KeyValueRecordType( key: "other", value: AppLocalizations.of(context).translate('other')), ]; return Scaffold( body: Container( child: Theme( data: Theme.of(context).copyWith( canvasColor: Colors.black, ), child: DropdownButton<KeyValueRecordType>( value: recordType, onChanged: (KeyValueRecordType value) { setState(() { recordType = value; //show selected value }); }, items: recordTypes .map<DropdownMenuItem<KeyValueRecordType>>( (recordType) => new DropdownMenuItem<KeyValueRecordType>( child: Text(recordType.value), value: recordType, )) .toList(), ), ), class KeyValueRecordType { String key; String value; KeyValueRecordType({this.key, this.value}); }
So the error is:
There should be exactly one item with [DropdownButton]'s value: Instance of 'KeyValueRecordType'. I/flutter ( 9900): Either zero or 2 or more [DropdownMenuItem]s were detected with the same value I/flutter ( 9900): 'package:flutter/src/material/dropdown.dart': I/flutter ( 9900): Failed assertion: line 834 pos 15: 'items == null || items.isEmpty || value == null || I/flutter ( 9900): items.where((DropdownMenuItem<T> item) { I/flutter ( 9900): return item.value == value; I/flutter ( 9900): }).length == 1'
I tried different approaches, when I specify recordType.key within onchanged I get error that this key does not exist. I tried also putting the List in FutureBuilder and in separate function, neither worked. As I need Context I cannot put it outside of the build method.