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

Flutter实现动态尺寸兴趣气泡界面:如何达成目标设计?

Flutter 实现自定义气泡选择组件

方案一:自定义实现(推荐,避免依赖包限制)

如果第三方包无法满足需求,直接自定义组件更灵活:

  • 1. 定义数据模型
    先创建包含选项文本、选中状态的模型:

    class BubbleOption {
      final String text;
      bool isSelected;
    
      BubbleOption({required this.text, this.isSelected = false});
    }
    
  • 2. 构建气泡组件
    用GestureDetector包裹Container实现点击切换选中状态,自定义样式:

    Widget _buildBubble(BubbleOption option, Function() onTap) {
      return GestureDetector(
        onTap: onTap,
        child: Container(
          margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          decoration: BoxDecoration(
            color: option.isSelected ? Colors.blueAccent : Colors.grey[200],
            borderRadius: BorderRadius.circular(20),
            border: Border.all(
              color: option.isSelected ? Colors.blueAccent : Colors.grey[300]!,
              width: 1.5,
            ),
          ),
          child: Text(
            option.text,
            style: TextStyle(
              color: option.isSelected ? Colors.white : Colors.grey[700],
              fontSize: 14,
              fontWeight: FontWeight.w500,
            ),
          ),
        ),
      );
    }
    
  • 3. 用Wrap组件排版
    把气泡放在Wrap里实现自动换行:

    class BubbleSelectionScreen extends StatefulWidget {
      @override
      _BubbleSelectionScreenState createState() => _BubbleSelectionScreenState();
    }
    
    class _BubbleSelectionScreenState extends State<BubbleSelectionScreen> {
      List<BubbleOption> options = [
        BubbleOption(text: "选项1"),
        BubbleOption(text: "较长的选项文本示例"),
        BubbleOption(text: "选项3"),
        BubbleOption(text: "选项4"),
        BubbleOption(text: "选项5"),
        BubbleOption(text: "选项6"),
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Wrap(
              spacing: 8,
              runSpacing: 8,
              children: options.map((option) {
                return _buildBubble(option, () {
                  setState(() {
                    option.isSelected = !option.isSelected;
                    // 若需单选,取消其他选项选中状态:
                    // options.forEach((opt) => opt.isSelected = opt == option);
                  });
                });
              }).toList(),
            ),
          ),
        );
      }
    }
    

方案二:修复bubbles_selection包的问题

如果坚持用该包,针对常见问题调整参数:

  • 调整排版参数:设置spacing和runSpacing控制气泡间距,确保alignment为WrapAlignment.start
  • 自定义选中样式:通过selectedStyle修改选中时的背景色、文字颜色,unSelectedStyle修改未选中状态
  • 示例代码:
    BubbleSelection(
      items: [
        BubbleItem(id: "1", title: "选项1"),
        BubbleItem(id: "2", title: "较长的选项文本示例"),
        // 更多选项...
      ],
      selectedStyle: BubbleStyle(
        backgroundColor: Colors.blueAccent,
        textStyle: TextStyle(color: Colors.white),
        borderColor: Colors.blueAccent,
      ),
      unSelectedStyle: BubbleStyle(
        backgroundColor: Colors.grey[200],
        textStyle: TextStyle(color: Colors.grey[700]),
        borderColor: Colors.grey[300]!,
      ),
      spacing: 8,
      runSpacing: 8,
      onChanged: (selectedItems) {
        // 处理选中逻辑
      },
    )
    

关键注意点

  • 如果需要单选逻辑,自定义实现时要遍历选项取消其他选中状态;用包的话查看是否支持单选模式(部分气泡选择包默认是多选)
  • 气泡的内边距、圆角大小要统一,保证视觉一致性
  • 文本超出气泡时可以设置TextOverflow.ellipsis避免换行错乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:46:10