如何在Flutter中为Checkbox设置渐变颜色(无需修改Container颜色)
实现渐变颜色的Checkbox
原生Flutter的Checkbox组件的activeColor参数仅支持单一Color类型,无法直接传入LinearGradient替代。不过可以通过以下两种方式实现渐变效果,无需额外修改Container颜色:
方法1:用ShaderMask包裹Checkbox
ShaderMask可以为子组件应用渐变着色,刚好适配给选中状态的Checkbox添加渐变效果。修改你的代码如下:
ValueListenableBuilder CheckSex(ValueNotifier<String?> sexNotifier) { return ValueListenableBuilder( valueListenable: sexNotifier, builder: (context, pickedSex, child) { return Row( children: ["Мужской", "Женский", "Другой"].map((String sex) { final isSelected = sex == pickedSex; return Row( children: [ Text(sex), ShaderMask( shaderCallback: (bounds) => LinearGradient( colors: [Colors.indigo[500]!, Colors.purple[400]!], begin: Alignment.topLeft, end: Alignment.bottomRight, ).createShader(bounds), blendMode: BlendMode.srcIn, child: Checkbox( activeColor: Colors.white, // 设为白色让渐变透出 checkColor: Colors.white, value: isSelected, onChanged: (pick) { sexNotifier.value = sex; }, ), ), ], ); }).toList(), ); }, ); }
原理是将Checkbox的activeColor设为白色,通过ShaderMask的渐变Shader覆盖,BlendMode.srcIn会让渐变仅显示Checkbox的形状区域。
方法2:自定义Checkbox外观
如果需要更灵活的样式控制,可以用GestureDetector结合CustomPaint完全自定义渐变Checkbox,适合高度定制的场景:
class GradientCheckbox extends StatefulWidget { final bool value; final ValueChanged<bool>? onChanged; final LinearGradient gradient; const GradientCheckbox({ super.key, required this.value, required this.onChanged, this.gradient = const LinearGradient(colors: [Colors.indigo, Colors.purple]), }); @override State<GradientCheckbox> createState() => _GradientCheckboxState(); } class _GradientCheckboxState extends State<GradientCheckbox> { late bool _selected; @override void initState() { super.initState(); _selected = widget.value; } @override void didUpdateWidget(covariant GradientCheckbox oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.value != widget.value) { _selected = widget.value; } } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { if (widget.onChanged != null) { setState(() => _selected = !_selected); widget.onChanged!(_selected); } }, child: CustomPaint( size: const Size(24, 24), painter: _GradientCheckboxPainter( isSelected: _selected, gradient: widget.gradient, ), ), ); } } class _GradientCheckboxPainter extends CustomPainter { final bool isSelected; final LinearGradient gradient; _GradientCheckboxPainter({required this.isSelected, required this.gradient}); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 2 ..color = isSelected ? Colors.transparent : Colors.grey[400]!; // 绘制边框 canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), const Radius.circular(4), ), paint, ); if (isSelected) { // 绘制渐变填充 final fillPaint = Paint() ..shader = gradient.createShader(Rect.fromLTWH(0, 0, size.width, size.height)); canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), const Radius.circular(4), ), fillPaint, ); // 绘制对勾 final checkPaint = Paint() ..color = Colors.white ..style = PaintingStyle.stroke ..strokeWidth = 2 ..strokeCap = StrokeCap.round; final path = Path(); path.moveTo(size.width * 0.25, size.height * 0.5); path.lineTo(size.width * 0.45, size.height * 0.7); path.lineTo(size.width * 0.75, size.height * 0.3); canvas.drawPath(path, checkPaint); } } @override bool shouldRepaint(covariant _GradientCheckboxPainter oldDelegate) { return oldDelegate.isSelected != isSelected || oldDelegate.gradient != gradient; } }
之后在你的代码中替换原生Checkbox为这个自定义组件即可:
// ... child: GradientCheckbox( value: sex == pickedSex, onChanged: (pick) { if (pick == true) { sexNotifier.value = sex; } }, ), // ...
内容的提问来源于stack exchange,提问作者Alexandr Sergo
相关产品推荐
相关产品推荐

