如何在Flutter中实现支持勾选功能的复选框组件
Flutter 自定义支持勾选操作的样式复选框实现方案
下面提供两种实现方案,可根据需求选择:
- 基于系统自带
Checkbox组件调整,开发成本低、适配性好,适合样式差异不大的需求 - 完全自定义Widget,灵活度高,可完全匹配设计稿的动效、样式细节,适合要求较高的场景
方案1:基于系统Checkbox组件调整
核心通过修改系统Checkbox的样式属性实现自定义效果,示例代码如下:
bool _isChecked = false; @override Widget build(BuildContext context) { return Checkbox( value: _isChecked, onChanged: (value) { setState(() { _isChecked = value ?? false; }); }, // 自定义填充颜色,区分选中/未选中状态 fillColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { return Colors.green; // 选中状态背景色,可替换为设计稿色值 } return Colors.white; // 未选中状态背景色 }), // 勾选标记的颜色 checkColor: Colors.white, // 自定义圆角,实现圆角矩形效果 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), // 未选中状态的边框样式 side: const BorderSide( color: Colors.grey, width: 1.5, ), ); }
方案2:完全自定义复选框组件
支持自定义勾选动画、样式细节,示例代码如下:
class CustomCheckbox extends StatefulWidget { final bool value; final ValueChanged<bool>? onChanged; final Color? checkedBgColor; final Color? uncheckedBgColor; final Color? borderColor; final Color? checkColor; final double radius; final double size; const CustomCheckbox({ super.key, required this.value, required this.onChanged, this.checkedBgColor = Colors.green, this.uncheckedBgColor = Colors.white, this.borderColor = Colors.grey, this.checkColor = Colors.white, this.radius = 4, this.size = 24, }); @override State<CustomCheckbox> createState() => _CustomCheckboxState(); } class _CustomCheckboxState extends State<CustomCheckbox> with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation<double> _scaleAnimation; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 150), ); _scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); } @override void didUpdateWidget(covariant CustomCheckbox oldWidget) { super.didUpdateWidget(oldWidget); widget.value ? _animationController.forward() : _animationController.reverse(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () => widget.onChanged?.call(!widget.value), child: AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) => Transform.scale( scale: _scaleAnimation.value, child: Container( width: widget.size, height: widget.size, decoration: BoxDecoration( color: widget.value ? widget.checkedBgColor : widget.uncheckedBgColor, borderRadius: BorderRadius.circular(widget.radius), border: Border.all( color: widget.value ? widget.checkedBgColor! : widget.borderColor!, width: 1.5, ), ), child: widget.value ? Icon(Icons.check, size: widget.size * 0.75, color: widget.checkColor) : const SizedBox(), ), ), ), ); } }
使用示例
bool _isChecked = false; // 直接在布局中调用即可 CustomCheckbox( value: _isChecked, onChanged: (value) { setState(() { _isChecked = value; }); }, )
注意事项
- 如果需要匹配指定设计样式,只需要调整对应参数的数值(比如圆角半径、边框宽度、图标大小、颜色值)即可完全还原设计效果
- 适配深色模式时,可将硬编码色值替换为
Theme.of(context)对应的主题色,实现自动适配
内容的提问来源于stack exchange,提问作者petrashin_nikita
相关产品推荐
相关产品推荐

