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

Flutter中如何在两个互斥切换按钮间嵌入TextField?

解决Flutter中带中间TextField的单选切换按钮布局问题

你可以通过自定义StatefulWidget来封装这组控件,把两个切换按钮和中间的TextField整合到同一个组件中,同时内部维护单选状态,既满足两个按钮属于同一组件的需求,也不会把TextField变成可点击的按钮项。

基础实现示例

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

  @override
  State<ToggleWithTextField> createState() => _ToggleWithTextFieldState();
}

class _ToggleWithTextFieldState extends State<ToggleWithTextField> {
  // 0代表左侧按钮选中,1代表右侧按钮选中
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        // 左侧切换按钮
        ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: _selectedIndex == 0 ? Colors.blue : Colors.grey[200],
            foregroundColor: _selectedIndex == 0 ? Colors.white : Colors.black,
          ),
          onPressed: () => setState(() => _selectedIndex = 0),
          child: const Text("按钮1"),
        ),
        const SizedBox(width: 16),
        // 中间的TextField,用Expanded占满剩余空间
        Expanded(
          child: TextField(
            decoration: const InputDecoration(
              hintText: "输入内容",
              border: OutlineInputBorder(),
            ),
          ),
        ),
        const SizedBox(width: 16),
        // 右侧切换按钮
        ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: _selectedIndex == 1 ? Colors.blue : Colors.grey[200],
            foregroundColor: _selectedIndex == 1 ? Colors.white : Colors.black,
          ),
          onPressed: () => setState(() => _selectedIndex = 1),
          child: const Text("按钮2"),
        ),
      ],
    );
  }
}

灵活扩展版本

如果需要支持自定义按钮文字、TextField控制器或监听切换事件,可以给组件添加参数:

class ToggleWithTextField extends StatefulWidget {
  final String leftButtonText;
  final String rightButtonText;
  final TextEditingController? textController;
  final ValueChanged<int>? onToggleChanged;

  const ToggleWithTextField({
    super.key,
    required this.leftButtonText,
    required this.rightButtonText,
    this.textController,
    this.onToggleChanged,
  });

  @override
  State<ToggleWithTextField> createState() => _ToggleWithTextFieldState();
}

class _ToggleWithTextFieldState extends State<ToggleWithTextField> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: _selectedIndex == 0 ? Colors.blue : Colors.grey[200],
            foregroundColor: _selectedIndex == 0 ? Colors.white : Colors.black,
          ),
          onPressed: () {
            setState(() => _selectedIndex = 0);
            widget.onToggleChanged?.call(0);
          },
          child: Text(widget.leftButtonText),
        ),
        const SizedBox(width: 16),
        Expanded(
          child: TextField(
            controller: widget.textController,
            decoration: const InputDecoration(
              hintText: "输入内容",
              border: OutlineInputBorder(),
            ),
          ),
        ),
        const SizedBox(width: 16),
        ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: _selectedIndex == 1 ? Colors.blue : Colors.grey[200],
            foregroundColor: _selectedIndex == 1 ? Colors.white : Colors.black,
          ),
          onPressed: () {
            setState(() => _selectedIndex = 1);
            widget.onToggleChanged?.call(1);
          },
          child: Text(widget.rightButtonText),
        ),
      ],
    );
  }
}

使用方式

在需要的地方直接调用这个自定义组件即可:

const ToggleWithTextField(
  leftButtonText: "选项A",
  rightButtonText: "选项B",
)

这种方案把两个按钮的单选逻辑完全封装在组件内部,符合你对“两个按钮属于同一组件”的要求,同时TextField独立于按钮的选中逻辑,不会被当作可点击的切换项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:36:20