You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter不同类型下拉菜单实现及自定义样式下拉组件开发问题咨询

需求样式参考

  • 默认状态
    默认状态
  • 聚焦状态
    聚焦状态
Flutter自定义下拉组件实现方案

方案1:第三方包快速实现

推荐使用flutter_typeahead成熟组件,可直接适配需求样式,无需自行处理位置锚定逻辑:

  1. 引入依赖到pubspec.yaml
dependencies:
  flutter_typeahead: ^5.2.0
  1. 基础实现代码
class CustomDropdown extends StatefulWidget {
  const CustomDropdown({super.key});

  @override
  State<CustomDropdown> createState() => _CustomDropdownState();
}

class _CustomDropdownState extends State<CustomDropdown> {
  final List<String> _optionList = ['选项1', '选项2', '选项3', '选项4'];
  String? _selectedVal;

  @override
  Widget build(BuildContext context) {
    return TypeAheadField<String>(
      // 自定义输入框样式,匹配默认状态
      builder: (context, controller, focusNode) {
        return TextField(
          controller: controller,
          focusNode: focusNode,
          decoration: InputDecoration(
            hintText: '请选择选项',
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide: const BorderSide(color: Colors.grey),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide: const BorderSide(color: Colors.blue, width: 2),
            ),
            suffixIcon: const Icon(Icons.arrow_drop_down),
            contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
          ),
          readOnly: true,
          onTap: () => focusNode.requestFocus(),
        );
      },
      // 下拉选项匹配逻辑,可自行添加搜索过滤
      suggestionsCallback: (searchStr) => _optionList.where((e) => e.contains(searchStr)).toList(),
      // 自定义下拉项样式
      itemBuilder: (context, option) {
        return Container(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          child: Text(option),
        );
      },
      // 选中后逻辑处理
      onSelected: (option) {
        setState(() {
          _selectedVal = option;
        });
      },
      // 下拉容器样式配置
      decorationBuilder: (context, child) {
        return Material(
          elevation: 4,
          borderRadius: BorderRadius.circular(8),
          child: child,
        );
      },
      itemSeparatorBuilder: (context, index) => const Divider(height: 1),
      hideOnEmpty: true,
    );
  }
}

方案2:全自定义实现(灵活度最高)

如果需要完全控制交互和样式,可通过CompositedTransformTarget+CompositedTransformFollower+Overlay组合实现,解决普通Overlay滚动错位问题:

  • 核心实现步骤:
    • 给输入框绑定LayerLink作为下拉框的位置锚点
    • 监听输入框焦点状态,聚焦时插入OverlayEntry展示下拉列表,失焦时移除
    • 下拉框组件外层包裹CompositedTransformFollower,绑定同一个LayerLink,自动跟随输入框位置
    • 自行实现下拉项的选中、高亮、点击回调逻辑即可

注意事项

  • 普通DropdownButton样式定制限制极多,无法实现输入框联动的圆角、悬浮阴影效果
  • 直接使用Overlay绝对定位会出现页面滚动时下拉框和输入框错位的问题,不要使用该方案
  • 选中下拉项后需要手动处理输入框文本赋值、焦点释放逻辑

内容的提问来源于stack exchange,提问作者Tanish Kapur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:36:00