如何在上下文中结合 Flutter 中的 DropdownMenu 和 AppLocalization?
How to combine DropdownMenu and AppLocalization in Flutter within context?
我在 flutter 中与 AppLocalization 一起使用下拉菜单时遇到问题。我在 phone 设置中实现了基于用户 selected 语言的自动本地化。在我还想实现具有本地化值的下拉菜单之前,它一直很好用。当我呈现下拉菜单时它可以工作但是在我 select 值 a 得到这样的错误 ,请注意我需要 KeyValueRecords 列表中的 appLocalization,
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});
}
所以错误是:
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'
我尝试了不同的方法,当我在 onchanged 中指定 recordType.key 时,我收到错误消息,指出此密钥不存在。我也尝试将 List 放在 FutureBuilder 和单独的函数中,但都没有用。因为我需要上下文,所以我不能把它放在 build 方法之外。
您可以复制粘贴 运行 下面的完整代码
您可以使用包 https://pub.dev/packages/equatable 并扩展 Equatable
代码片段
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];
}
工作演示
完整代码
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(),
);
}
}
我在 flutter 中与 AppLocalization 一起使用下拉菜单时遇到问题。我在 phone 设置中实现了基于用户 selected 语言的自动本地化。在我还想实现具有本地化值的下拉菜单之前,它一直很好用。当我呈现下拉菜单时它可以工作但是在我 select 值 a 得到这样的错误
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});
}
所以错误是:
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'
我尝试了不同的方法,当我在 onchanged 中指定 recordType.key 时,我收到错误消息,指出此密钥不存在。我也尝试将 List 放在 FutureBuilder 和单独的函数中,但都没有用。因为我需要上下文,所以我不能把它放在 build 方法之外。
您可以复制粘贴 运行 下面的完整代码
您可以使用包 https://pub.dev/packages/equatable 并扩展 Equatable
代码片段
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];
}
工作演示
完整代码
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(),
);
}
}