Flutter中如何禁止用户在DropdownMenu组件中输入内容?
我需要禁止用户在DropdownMenu组件中输入内容,但未找到实现方法,查阅官方文档也无相关信息。当前使用的DropdownMenu组件允许用户输入,想要实现类似DropdownButton2包的不可输入下拉选择效果。
代码实现
class TDSMDropdown extends StatefulWidget { final List<String> items; final String? value; final String? hintText; final String? label; final void Function(String?)? onSelected; final TextEditingController? controller; const TDSMDropdown({ Key? key, required this.items, this.value, this.hintText, required this.label, this.onSelected, this.controller, }) : super(key: key); @override State<TDSMDropdown> createState() => _TDSMDropdownState(); } class _TDSMDropdownState extends State<TDSMDropdown> { // final TextEditingController colorController = TextEditingController(); String? selectedValue; @override void initState() { super.initState(); selectedValue = widget.value; } _handleOnSelected(String? newVal) { widget.onSelected!(newVal); } @override Widget build(BuildContext context) { return DropdownMenu<String>( width: MediaQuery.of(context).size.width, enableSearch: false, // controller: colorController, label: widget.label == null ? null : Text(widget.label!), dropdownMenuEntries: widget.items .map((e) => DropdownMenuEntry<String>(value: e, label: e)) .toList(), // inputDecorationTheme: _decoration(), onSelected: widget.onSelected != null ? _handleOnSelected : null, ); } }
环境信息
- Flutter版本 3.7.0
- Material 3
- Dart版本 2.19.0
解决方案
可以通过以下两种方式实现DropdownMenu的不可输入效果:
方法一:通过输入主题配置禁用输入
在DropdownMenu的inputDecorationTheme中设置输入框为禁用状态,同时调整样式避免视觉上的禁用感:
@override Widget build(BuildContext context) { return DropdownMenu<String>( width: MediaQuery.of(context).size.width, enableSearch: false, label: widget.label == null ? null : Text(widget.label!), dropdownMenuEntries: widget.items .map((e) => DropdownMenuEntry<String>(value: e, label: e)) .toList(), onSelected: widget.onSelected != null ? _handleOnSelected : null, // 配置输入主题禁用输入并调整样式 inputDecorationTheme: InputDecorationTheme( enabled: false, disabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Theme.of(context).colorScheme.outline), ), disabledTextStyle: TextStyle(color: Theme.of(context).colorScheme.onSurface), ), ); }
方法二:拦截输入行为并控制文本
通过控制器管理选中值,同时拦截输入框的焦点和输入动作,保留组件视觉样式的同时禁止输入:
@override Widget build(BuildContext context) { final textController = widget.controller ?? TextEditingController(text: selectedValue); return DropdownMenu<String>( width: MediaQuery.of(context).size.width, enableSearch: false, controller: textController, label: widget.label == null ? null : Text(widget.label!), dropdownMenuEntries: widget.items .map((e) => DropdownMenuEntry<String>(value: e, label: e)) .toList(), onSelected: (newVal) { widget.onSelected?.call(newVal); setState(() { selectedValue = newVal; textController.text = newVal ?? ''; }); }, // 拦截输入相关行为 textInputAction: TextInputAction.none, onTap: () => FocusScope.of(context).unfocus(), inputDecorationTheme: InputDecorationTheme( enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Theme.of(context).colorScheme.outline), ), ), ); }
注意事项
- 方法一设置
enabled: false会触发组件的禁用状态,必须自定义样式保持视觉上的可用感,避免用户误解。 - 方法二更灵活,既能禁止输入,又能完全保留组件的原生视觉样式。
内容的提问来源于stack exchange,提问作者Labrador
相关产品推荐
相关产品推荐

