开源一个Flutter功能引导小工具,给大家介绍一下
先上仓库
介绍
里面讲解了大致的思路和简单的示例代码,不过使用ColorFiltered去实现的时候发现了一些问题,在某些iOS设备上蒙层效果失效了,查阅一些资料后暂且认为是Flutter的渲染引擎在不同的平台上的体现不一致。
这里我使用CustomPainter配合Path的混合重新实现了这个效果,更加灵活和稳定。
使用比较简单,目前仅支持提示区旁展示文本,有足够多的配置项支持一些简约的设计场景。希望能帮到各位开发者🚀
希望能给各位提供帮助,也希望大家能给个like或star鼓励一下,感恩!
核心代码
CustomPainter实现
class MaskingPainter extends CustomPainter {
/// ...
@override
void paint(Canvas canvas, Size size) {
/// 绘制蒙层
_drawMasking(canvas, size);
/// 绘制提示文本
_drawDescription(canvas, size);
}
}
_drawMasking(Canvas canvas, Size size) {
double left = 0;
double top = 0;
double right = 0;
double bottom = 0;
left = show.drawRect.left - show.rectPadding.left;
if (next != null) {
left = left + (next!.drawRect.left - left) * controller.value;
}
top = show.drawRect.top - show.rectPadding.top;
if (next != null) {
top = top + (next!.drawRect.top - top) * controller.value;
}
right = show.drawRect.right + show.rectPadding.right;
if (next != null) {
right = right + (next!.drawRect.right - right) * controller.value;
}
bottom = show.drawRect.bottom + show.rectPadding.bottom;
if (next != null) {
bottom = bottom + (next!.drawRect.bottom - bottom) * controller.value;
}
final outerPath = Path()
..addRect(Rect.fromLTWH(0, 0, size.width, size.height));
final innerPath = Path()
..addRRect(RRect.fromLTRBAndCorners(
left,
top,
right,
bottom,
topLeft: show.borderRadius.topLeft,
topRight: show.borderRadius.topRight,
bottomLeft: show.borderRadius.bottomLeft,
bottomRight: show.borderRadius.bottomRight,
));
final path = Path.combine(PathOperation.difference, outerPath, innerPath);
final paint = Paint()..color = Colors.black.withOpacity(opacity);
canvas.drawPath(path, paint);
}
功能介绍
- 支持
Widget#key
或Rect
锁定提示位置 - 支持背景蒙版透明度设置
- 支持动画过渡时长设置
- 支持提示文本自定义样式设置
- 支持提示文本位置预制选项设置
- 支持提示区域内边距设置
- 支持提示区域圆角设置
- 支持提示文本与提示区域间距设置
如何使用?
- 使用GlobalKey标记要提示的区域
child: Text(
"count=$count",
key: guidanceAreaKey,
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
- 直接使用Rect标记要提示的区域
Rect guidanceAreaRect = const Rect.fromLTRB(10, 20, 100, 200);
然后你需要在页面绘制完成后,准备你的GuideManager
,最后进行show
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
guideManager ??= GuideManager(context, opacity: 0.7);
guideManager!.prepare([
GuideItem(
description: "对于提示区的文本描述(使用Key)",
toGuideKey: guidanceAreaKey,
padding: EdgeInsets.zero,
),
GuideItem(
description: "对于提示区的文本描述(使用Rect)",
toGuideRect: guidanceAreaRect,
padding: EdgeInsets.zero,
),
]);
guideManager!.show();
});
}
预览图

无论使用还是学习,都欢迎前往github查阅!
转载自:https://juejin.cn/post/7300122001767661568