Flutter下拉菜单所选项目样式与项目不同

fdx2calv  于 2023-03-04  发布在  Flutter
关注(0)|答案(1)|浏览(159)

我正在为用户开发一个UI来更改应用程序语言。
当显示当前选择的语言时,我希望只显示带有下拉图标的标志。当用户单击下拉按钮时,我希望添加该语言的完整字符串表示。
我似乎找不到一种方法来使选定的项目看起来不同于菜单项。
我想要的:此为未打开的下拉列表:

我想要的:此为打开的下拉列表:

不需要:

不需要:

我只得到文本为两者或只是标志为两者,但从来没有如所愿。
迄今为止的守则:

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 }

我看了flutter dev,搜索了stackoverflow,谷歌了一下,试图自己改变一些东西。

mctunoxg

mctunoxg1#

看起来您需要使用DropdownButtonselectedItemBuilder
下面是一个示例,您可以尝试插入数据以获得所需的输出:

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(),
    );
  }
}

注意:SizedBox很重要,因此它不会抛出视口错误。

相关问题