Flutter下拉框选中的项目样式与其他项目不同

huangapple go评论63阅读模式
英文:

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:
Flutter下拉框选中的项目样式与其他项目不同
What I want: This for opened dropdown:
Flutter下拉框选中的项目样式与其他项目不同

Unwanted:
Flutter下拉框选中的项目样式与其他项目不同
Unwanted:
Flutter下拉框选中的项目样式与其他项目不同

I only get text for both or just flag for both, but never as desired.

The Code so far:

DropdownButton(
  items: LanguageUtils.getSupportedLanguagesAsStringList()
      .map&lt;DropdownMenuItem&lt;String&gt;&gt;((String langCodeString) {
    return DropdownMenuItem&lt;String&gt;(
      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&lt;Widget&gt; 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 &quot;English&quot;;
        break;
      case LangCode.de:
        return &quot;Deutsch&quot;;
        break;
    }
  }

  /// Get short rep of language code to use programmatically when exporting state.
  static String getStringRepForLangCode(LangCode langCodeToGetStringFor) {
    switch (langCodeToGetStringFor) {
      case LangCode.en:
        return &quot;en&quot;;
        break;
      case LangCode.de:
        return &quot;de&quot;;
        break;
    }
  }

  /// Get all supported LangCodes as string rep to create dropdown menu from.
  static List&lt;String&gt; getSupportedLanguagesAsStringList() {
    return LangCode.values.map((e) =&gt; e.name).toList();
  }

  /// To return LangCode from its converted rep.
  ///
  /// Defaults to en =&gt; Failsafe, always returns valid LangCode.
  static LangCode getLangCodeFromItsStringRep(String langCodeAsString) {
    switch (langCodeAsString) {
      case &quot;de&quot;:
        return LangCode.de;
        break;

      case &quot;en&quot;:
      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

看起来你需要使用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,
      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 &#39;package:flutter/material.dart&#39;;
const List&lt;String&gt; list = &lt;String&gt;[&#39;One  &#39;, &#39;Two &#39;, &#39;Three&#39;, &#39;Four&#39;];
void main() =&gt; 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(&#39;DropdownButton Sample&#39;)),
body: const Center(
child: DropdownButtonExample(),
),
),
);
}
}
class DropdownButtonExample extends StatefulWidget {
const DropdownButtonExample({super.key});
@override
State&lt;DropdownButtonExample&gt; createState() =&gt; _DropdownButtonExampleState();
}
class _DropdownButtonExampleState extends State&lt;DropdownButtonExample&gt; {
String dropdownValue = list.first;
@override
Widget build(BuildContext context) {
return DropdownButton&lt;String&gt;(
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) =&gt;
List.generate(1,
(i) =&gt; 
const SizedBox(
width: 50,
child: Icon(Icons.flag)
)
),
items: list.map&lt;DropdownMenuItem&lt;String&gt;&gt;((String value) {
return DropdownMenuItem&lt;String&gt;(
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.

huangapple
  • 本文由 发表于 2023年2月27日 14:43:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75577417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定