Flutter中如何实现选中项高亮、未选中项模糊虚化的效果?
Flutter单选状态按钮组实现方案
实现核心逻辑
- 用
StatefulWidget维护当前选中的按钮索引,初始值可以设为-1(无选中状态)或者默认选中第一项 - 遍历生成每个选项按钮时,对比当前按钮索引是否等于选中索引:
- 选中项:使用高亮样式(背景色加深、文字颜色反白、无虚化效果)
- 未选中项:降低透明度+添加模糊滤镜,弱化视觉效果
- 点击按钮时更新选中索引,触发UI重绘即可同步所有按钮状态
完整可运行示例代码
import 'package:flutter/material.dart'; import 'dart:ui'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: const Center( child: StatusSelector( options: ["待处理", "进行中", "已完成", "已取消"], ), ), ), ); } } class StatusSelector extends StatefulWidget { final List<String> options; final Function(int index)? onSelected; final int? defaultSelectedIndex; const StatusSelector({ super.key, required this.options, this.onSelected, this.defaultSelectedIndex, }); @override State<StatusSelector> createState() => _StatusSelectorState(); } class _StatusSelectorState extends State<StatusSelector> { late int selectedIndex; @override void initState() { super.initState(); selectedIndex = widget.defaultSelectedIndex ?? -1; } @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(widget.options.length, (index) { final isSelected = selectedIndex == index; return Padding( padding: const EdgeInsets.symmetric(horizontal: 6), child: GestureDetector( onTap: () { setState(() { selectedIndex = index; }); widget.onSelected?.call(index); }, // 未选中项添加高斯模糊效果 child: ImageFiltered( imageFilter: isSelected ? ImageFilter.blur(sigmaX: 0, sigmaY: 0) : ImageFilter.blur(sigmaX: 1.2, sigmaY: 1.2), child: Opacity( // 未选中项降低透明度进一步弱化 opacity: isSelected ? 1 : 0.5, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: isSelected ? Colors.blueAccent : Colors.grey[200], borderRadius: BorderRadius.circular(20), ), child: Text( widget.options[index], style: TextStyle( color: isSelected ? Colors.white : Colors.grey[700], fontSize: 14, ), ), ), ), ), ), ); }), ); } }
样式调整说明
- 若不需要高斯模糊,直接删除
ImageFiltered组件,只保留Opacity控制透明度即可实现弱化效果 - 可以根据需求修改选中态的背景色、圆角、内边距,匹配你的应用设计风格
- 如果需要支持取消选中,点击时判断当前点击索引是否等于已选中索引,将
selectedIndex设为-1即可
内容的提问来源于stack exchange,提问作者Bunthong K
相关产品推荐
相关产品推荐

