CupertinoThumbPainter
专门用于绘制iOS风格滑块(slider)的圆形拇指(thumb)部分
CupertinoThumbPainter是Flutter Cupertino风格设计库中一个低级的绘制组件,它专门用于绘制iOS风格滑块(slider)的圆形拇指(thumb)部分。它不直接是一个可交互的widget,而是一个BoxDecoration的自定义绘制器,主要职责
是根据指定状态(如是否按下)来绘制一个具有阴影和特定背景色的圆形。
主要用途
- 为
CupertinoSlider这类iOS风格的滑块提供统一的拇指绘制逻辑。 - 允许开发者自定义或扩展滑块拇指的视觉效果,同时保持iOS原生设计感。
使用场景
- 当您需要构建一个符合iOS设计规范的滑动选择器时,
CupertinoThumbPainter在底层帮助实现了滑块拇指的视觉效果。 - 在自定义滑动条时,如果您想复用iOS风格的拇指绘制逻辑,可以将其集成到自定义的
CustomPainter或BoxDecoration中。
示例
基本Thumb绘制
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class BasicThumbPainterExample extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Basic CupertinoThumbPainter'),
),
body: Center(
child: Container(
width: 100, // 增加容器宽度以容纳阴影
height: 100, // 增加容器高度以容纳阴影
color: Colors.grey[200], // 提供背景色以衬托拇指
child: CustomPaint(
painter: _ThumbPainter(
color: CupertinoColors.white,
pressed: false, // 未按下状态
),
child: Center(
child: Text('Thumb', style: TextStyle(color: Colors.black)),
),
),
),
),
);
}
}
class _ThumbPainter extends CustomPainter {
final Color color;
final bool pressed;
_ThumbPainter({required this.color, required this.pressed});
void paint(Canvas canvas, Size size) {
final double radius = size.width / 2; // 假设绘制一个圆形,半径是宽度的一半
final Offset center = Offset(size.width / 2, size.height / 2);
// 调用 CupertinoThumbPainter 的 paint 方法来绘制拇指
CupertinoThumbPainter.paint(
canvas,
Rect.fromCircle(center: center, radius: radius),
color,
pressed,
);
}
bool shouldRepaint(_ThumbPainter oldDelegate) {
return oldDelegate.color != color || oldDelegate.pressed != pressed;
}
}
// void main() => runApp(MaterialApp(home: BasicThumbPainterExample()));
模拟按下状态
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class PressedThumbPainterExample extends StatefulWidget {
_PressedThumbPainterExampleState createState() => _PressedThumbPainterExampleState();
}
class _PressedThumbPainterExampleState extends State<PressedThumbPainterExample> {
bool _isPressed = false;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Pressed CupertinoThumbPainter'),
),
body: Center(
child: GestureDetector(
onTapDown: (_) {
setState(() {
_isPressed = true;
});
},
onTapUp: (_) {
setState(() {
_isPressed = false;
});
},
onTapCancel: () {
setState(() {
_isPressed = false;
});
},
child: Container(
width: 100,
height: 100,
color: Colors.grey[200],
child: CustomPaint(
painter: _ThumbPainter(
color: CupertinoColors.white,
pressed: _isPressed, // 根据状态变化
),
child: Center(
child: Text(
_isPressed ? 'Pressed' : 'Unpressed',
style: TextStyle(color: Colors.black),
),
),
),
),
),
),
);
}
}
// _ThumbPainter 和前面示例一致
class _ThumbPainter extends CustomPainter {
final Color color;
final bool pressed;
_ThumbPainter({required this.color, required this.pressed});
void paint(Canvas canvas, Size size) {
final double radius = size.width / 2;
final Offset center = Offset(size.width / 2, size.height / 2);
CupertinoThumbPainter.paint(
canvas,
Rect.fromCircle(center: center, radius: radius),
color,
pressed,
);
}
bool shouldRepaint(_ThumbPainter oldDelegate) {
return oldDelegate.color != color || oldDelegate.pressed != pressed;
}
}
// void main() => runApp(MaterialApp(home: PressedThumbPainterExample()));
注意点
- 这是一个低级绘制工具,不是
Widget: CupertinoThumbPainter本身不具备布局能力,它只是提供一个静态的paint方法来在指定的Canvas上绘制图形。您需要将其与CustomPaint或其他绘制上下文结合使用。 - 尺寸和位置:
paint方法需要一个Rect来指定绘制区域和大小。这个Rect定义了拇指的边界。在上述示例中,我们假设了圆形,并计算了合适的Rect。 - 阴影效果:
CupertinoThumbPainter的核心功能之一就是绘制不同状态下的阴影效果,以模拟iOS原生滑块的视觉反馈。 - 主题适配: 绘制的颜色
color可以根据CupertinoTheme或其他主题颜色进行动态调整,以确保与应用整体风格一致。 - 性能: 作为一个纯绘制函数,其性能通常不是瓶颈。但如果在
CustomPainter中频繁重绘,且shouldRepaint逻辑不当,仍可能导致不必要的渲染。
构造函数
CupertinoThumbPainter没有公共构造函数。它是一个工具类,其唯一的公共接口是静态方法paint。
属性
| 属性名 | 属性类型 | 说明 |
|---|---|---|
canvas | Canvas | 绘制的目标画布。 |
rect | Rect | 定义了拇指绘制的边界和大小。拇指会在此 Rect 内部绘制,包括其阴影。 |
color | Color | 拇指的背景颜色。通常默认为 CupertinoColors.white。 |
pressed | bool | 表示拇指是否处于被按下的状态。true 表示按下,false 表示未按下。不同状态下,会绘制出略微不同的阴影效果,以提供触觉反馈。 |
关键属性解释
rect: 这个参数至关重要,它直接决定了CupertinoThumbPainter绘制出的拇指的大小和在画布上的位置。开发者需要根据其父组件或使用场景来精确计算这个Rect的值。pressed: 这是控制拇指视觉反馈的核心参数。当设为true时,CupertinoThumbPainter会绘制一个“更深”或“更突出”的阴影,模拟真实世界中物体被按压时的效果;当设为false时,则绘制一个“平坦”的阴影。这种细微的视觉差异是iOS设计语言的重要组成部分。