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

如何为手机号输入框添加DropdownMenu下拉菜单

给手机号输入框添加DropdownMenu下拉菜单的实现方案

根据你的需求,这里提供两种常见的实现方式,适配Flutter的DropdownMenu组件或DropdownButtonFormField组件:

方式一:集成DropdownMenu到输入框右侧

这种方式是在现有TextField的右侧添加触发按钮,点击展开下拉菜单选择选项(比如国家码):

class PhoneInputWithDropdown extends StatefulWidget {
  const PhoneInputWithDropdown({super.key});

  @override
  State<PhoneInputWithDropdown> createState() => _PhoneInputWithDropdownState();
}

class _PhoneInputWithDropdownState extends State<PhoneInputWithDropdown> {
  final TextEditingController _phoneController = TextEditingController();
  String? _selectedCode;
  final List<String> _codeOptions = ['+86', '+1', '+44', '+61'];
  bool _showMenu = false;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 400,
      height: 60,
      child: Stack(
        alignment: Alignment.centerRight,
        children: [
          TextField(
            controller: _phoneController,
            style: body1(color: ColorName.neutralTextPrimary),
            decoration: InputDecoration(
              enabledBorder: OutlineInputBorder(
                borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
                borderRadius: BorderRadius.circular(10),
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10),
                borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
              ),
              hintText: 'Phone Number',
              hintStyle: body1(color: ColorName.neutralTextSecondary),
              prefixText: _selectedCode ?? '+86 ',
              contentPadding: const EdgeInsets.symmetric(horizontal: 16),
            ),
          ),
          // 触发下拉菜单的按钮
          IconButton(
            icon: Icon(
              _showMenu ? Icons.arrow_drop_up : Icons.arrow_drop_down,
              color: ColorName.neutralTextSecondary,
            ),
            onPressed: () => setState(() => _showMenu = !_showMenu),
          ),
          // 下拉菜单
          if (_showMenu)
            Positioned(
              top: 60,
              left: 0,
              right: 0,
              child: Material(
                borderRadius: BorderRadius.circular(10),
                elevation: 4,
                child: DropdownMenu<String>(
                  initialSelection: _selectedCode,
                  dropdownMenuEntries: _codeOptions
                      .map((code) => DropdownMenuEntry(value: code, label: code))
                      .toList(),
                  onSelected: (value) {
                    setState(() {
                      _selectedCode = value;
                      _showMenu = false;
                    });
                  },
                ),
              ),
            ),
        ],
      ),
    );
  }
}

关键说明:

  • 用StatefulWidget维护选中的选项和菜单显示状态
  • Stack布局让下拉菜单定位在输入框下方
  • 选中选项后自动关闭菜单,并更新输入框的前缀文本

方式二:拆分下拉框与输入框(更适合手机号场景)

如果是选择国家码+输入手机号的场景,用Row拆分两个组件,视觉上保持统一:

class PhoneCodeInput extends StatefulWidget {
  const PhoneCodeInput({super.key});

  @override
  State<PhoneCodeInput> createState() => _PhoneCodeInputState();
}

class _PhoneCodeInputState extends State<PhoneCodeInput> {
  final TextEditingController _phoneController = TextEditingController();
  String? _selectedCode;
  final List<String> _codeOptions = ['+86', '+1', '+44', '+61'];

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 400,
      height: 60,
      child: Row(
        children: [
          // 国家码下拉框
          SizedBox(
            width: 100,
            child: DropdownButtonFormField<String>(
              value: _selectedCode,
              decoration: InputDecoration(
                enabledBorder: OutlineInputBorder(
                  borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
                  borderRadius: const BorderRadius.only(
                    topLeft: Radius.circular(10),
                    bottomLeft: Radius.circular(10),
                  ),
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius: const BorderRadius.only(
                    topLeft: Radius.circular(10),
                    bottomLeft: Radius.circular(10),
                  ),
                  borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
                ),
                hintText: 'Code',
                hintStyle: body1(color: ColorName.neutralTextSecondary),
                contentPadding: const EdgeInsets.symmetric(horizontal: 8),
              ),
              items: _codeOptions
                  .map((code) => DropdownMenuItem(value: code, child: Text(code)))
                  .toList(),
              onChanged: (value) => setState(() => _selectedCode = value),
            ),
          ),
          // 手机号输入框
          Expanded(
            child: TextField(
              controller: _phoneController,
              style: body1(color: ColorName.neutralTextPrimary),
              decoration: InputDecoration(
                enabledBorder: OutlineInputBorder(
                  borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
                  borderRadius: const BorderRadius.only(
                    topRight: Radius.circular(10),
                    bottomRight: Radius.circular(10),
                  ),
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius: const BorderRadius.only(
                    topRight: Radius.circular(10),
                    bottomRight: Radius.circular(10),
                  ),
                  borderSide: const BorderSide(color: ColorName.neutralTextSecondary),
                ),
                hintText: 'Phone Number',
                hintStyle: body1(color: ColorName.neutralTextSecondary),
                contentPadding: const EdgeInsets.symmetric(horizontal: 16),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

关键说明:

  • 拆分后的组件分别设置左右圆角,视觉上形成一个完整的输入框
  • DropdownButtonFormField自带表单集成,无需手动管理菜单状态
  • 更符合手机号输入的用户习惯

内容的提问来源于stack exchange,提问作者Bilbo Baggins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 22:40:57