英文:
Flutter Dropdown Different Selected Item Style than Items
问题
以下是您要求的翻译部分:
DropdownButton(
items: LanguageUtils.getSupportedLanguagesAsStringList()
.map<DropdownMenuItem<String>>((String langCodeString) {
return DropdownMenuItem<String>(
value: langCodeString,
child: buildLanguageRowForDropDownButton(
langCode:
LanguageUtils.getLangCodeFromItsStringRep(langCodeString)),
);
}).toList(),
value: LanguageUtils.getStringRepForLangCode(_chosenLangCode),
onChanged: (String? value) {
changeLanguage();
},
);
/// 构建在下拉菜单中显示的行。
Row buildLanguageRowForDropDownButton({LangCode? langCode}) {
// 使用当前的_chosenLangCode作为默认值。
langCode = langCode ?? _chosenLangCode;
// 从设置构建行。
List<Widget> rowElements = [];
if (showFlag) {
rowElements.add(getImageOfLangCode(langCode: langCode));
}
if (showWrittenLanguage) {
rowElements
.add(Text(LanguageUtils.getFullNameForLangCode(langCode)));
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: rowElements,
);
}
// LanguageUtils
/// 围绕设置应用程序翻译语言的功能。
class LanguageUtils {
LanguageUtils() {}
/// 获取要显示给用户的语言的书面表示。
static String getFullNameForLangCode(LangCode langCodeToGetStringFor) {
switch (langCodeToGetStringFor) {
case LangCode.en:
return "English";
break;
case LangCode.de:
return "Deutsch";
break;
}
}
/// 获取用于在导出状态时以编程方式使用的语言代码的短表示。
static String getStringRepForLangCode(LangCode langCodeToGetStringFor) {
switch (langCodeToGetStringFor) {
case LangCode.en:
return "en";
break;
case LangCode.de:
return "de";
break;
}
}
/// 获取所有支持的LangCodes的字符串表示,以创建下拉菜单。
static List<String> getSupportedLanguagesAsStringList() {
return LangCode.values.map((e) => e.name).toList();
}
/// 从其转换表示返回LangCode。
///
/// 默认为en => 安全,始终返回有效的LangCode。
static LangCode getLangCodeFromItsStringRep(String langCodeAsString) {
switch (langCodeAsString) {
case "de":
return LangCode.de;
break;
case "en":
default:
return LangCode.en;
break;
}
}
}
/// 支持的语言。
enum LangCode { en, de }
希望这些翻译对您有所帮助。如有其他疑问,请随时提出。
英文:
I am developping an UI for the user to change the app language.
When showing the currently selected language I want to only display the flag with a dropdown icon. When the user clicks on the dropdown button I want the full string representation of the language to be added.
I can't seem to find a way to make the the selected item to look different than the menu items.
What I want:
This for unopened dropdown:
What I want: This for opened dropdown:
I only get text for both or just flag for both, but never as desired.
The Code so far:
DropdownButton(
items: LanguageUtils.getSupportedLanguagesAsStringList()
.map<DropdownMenuItem<String>>((String langCodeString) {
return DropdownMenuItem<String>(
value: langCodeString,
child: buildLanguageRowForDropDownButton(
langCode:
LanguageUtils.getLangCodeFromItsStringRep(langCodeString)),
);
}).toList(),
value: LanguageUtils.getStringRepForLangCode(_chosenLangCode),
onChanged: (String? value) {
changeLanguage();
},
);
/// Build row to be displayed in DropDownMenu.
Row buildLanguageRowForDropDownButton({LangCode? langCode}) {
// Use currently _chosenLangCode as default.
langCode = langCode ?? _chosenLangCode;
// Build row from settings.
List<Widget> rowElements = [];
if (showFlag) {
rowElements.add(getImageOfLangCode(langCode: langCode));
}
if (showWrittenLanguage) {
rowElements
.add(Text(LanguageUtils.getFullNameForLangCode(langCode)));
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: rowElements,
);
}
// LanguageUtils
/// Functions around setting app translation language.
class LanguageUtils {
LanguageUtils() {}
/// Get written rep of language to display to user.
static String getFullNameForLangCode(LangCode langCodeToGetStringFor) {
switch (langCodeToGetStringFor) {
case LangCode.en:
return "English";
break;
case LangCode.de:
return "Deutsch";
break;
}
}
/// Get short rep of language code to use programmatically when exporting state.
static String getStringRepForLangCode(LangCode langCodeToGetStringFor) {
switch (langCodeToGetStringFor) {
case LangCode.en:
return "en";
break;
case LangCode.de:
return "de";
break;
}
}
/// Get all supported LangCodes as string rep to create dropdown menu from.
static List<String> getSupportedLanguagesAsStringList() {
return LangCode.values.map((e) => e.name).toList();
}
/// To return LangCode from its converted rep.
///
/// Defaults to en => Failsafe, always returns valid LangCode.
static LangCode getLangCodeFromItsStringRep(String langCodeAsString) {
switch (langCodeAsString) {
case "de":
return LangCode.de;
break;
case "en":
default:
return LangCode.en;
break;
}
}
}
/// Supported Languages.
enum LangCode { en, de }
I looked at flutter dev, searched stackoverflow, googled and attempted to change things on my own.
答案1
得分: 2
看起来你需要使用DropdownButton
的selectedItemBuilder
。
以下是一个示例,你可以尝试并插入你的数据以获得所需的输出:
import 'package:flutter/material.dart';
const List<String> list = <String>['One ', 'Two ', 'Three', 'Four'];
void main() => runApp(const DropdownButtonApp());
class DropdownButtonApp extends StatelessWidget {
const DropdownButtonApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('DropdownButton Sample')),
body: const Center(
child: DropdownButtonExample(),
),
),
);
}
}
class DropdownButtonExample extends StatefulWidget {
const DropdownButtonExample({super.key});
@override
State<DropdownButtonExample> createState() => _DropdownButtonExampleState();
}
class _DropdownButtonExampleState extends State<DropdownButtonExample> {
String dropdownValue = list.first;
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? value) {
// 用户选择项目时调用此函数。
setState(() {
dropdownValue = value!;
});
},
selectedItemBuilder: (context) =>
List.generate(1,
(i) =>
const SizedBox(
width: 50,
child: Icon(Icons.flag)
)
),
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [const Icon(Icons.flag), Text(value)],
),
),
);
}).toList(),
);
}
}
注意:SizedBox
很重要,这样它就不会引发视口错误。
英文:
Looks like you need to use the selectedItemBuilder
of DropdownButton
.
Here's an example you can try and plug in your data to get the desired output:
import 'package:flutter/material.dart';
const List<String> list = <String>['One ', 'Two ', 'Three', 'Four'];
void main() => runApp(const DropdownButtonApp());
class DropdownButtonApp extends StatelessWidget {
const DropdownButtonApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('DropdownButton Sample')),
body: const Center(
child: DropdownButtonExample(),
),
),
);
}
}
class DropdownButtonExample extends StatefulWidget {
const DropdownButtonExample({super.key});
@override
State<DropdownButtonExample> createState() => _DropdownButtonExampleState();
}
class _DropdownButtonExampleState extends State<DropdownButtonExample> {
String dropdownValue = list.first;
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
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!;
});
},
selectedItemBuilder: (context) =>
List.generate(1,
(i) =>
const SizedBox(
width: 50,
child: Icon(Icons.flag)
)
),
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [const Icon(Icons.flag), Text(value)],
),
),
);
}).toList(),
);
}
}
Note: SizedBox is important so it doesn't throw viewport errors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论