Flutter遮罩引导插件mask_guide的使用
Flutter遮罩引导插件mask_guide的使用
Masked guide implemented with ColorFilter, 参考自 https://juejin.cn/post/7089087097218269197
Getting started
在项目中引入 mask_guide
插件:
import 'package:mask_guide/mask_guide.dart';
Usage
首先,在 MaterialApp()
中添加 MaskGuideNavigatorObserver()
MaterialApp(
navigatorObservers: [MaskGuideNavigatorObserver()],
)
使用自定义步骤小部件
如果您需要自定义步骤小部件,可以扩展 StepWidget
并覆盖 preStep
、nextStep
和 doneCallBack
。
创建自定义步骤小部件时,您需要手动计算小部件的位置。
class CustomStepWidget extends StepWidget {
[@override](/user/override)
void preStep() {
super.preStep();
// TODO: 执行一些操作
}
[@override](/user/override)
void nextStep() {
super.nextStep();
// TODO: 执行一些操作
}
[@override](/user/override)
void doneCallBack() {
super.doneCallBack();
// TODO: 执行一些操作
}
}
更多示例请查看 example。
示例代码
以下是完整的示例代码,展示了如何使用 mask_guide
插件。
文件结构
lib/
├── main.dart
└── custom_step_widget.dart
main.dart
import 'package:flutter/material.dart';
import 'package:mask_guide/mask_guide.dart';
import 'package:mask_guide_example/custom_step_widget.dart'; // 自定义步骤小部件
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
navigatorObservers: [MaskGuideNavigatorObserver()], // 添加观察器
home: const FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
const FirstPage({Key? key}) : super(key: key);
[@override](/user/override)
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
bool autoStart = false;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('First Page')),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => MyHomePage(autoStart: autoStart)));
},
child: const Text('Start'),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('自动显示:'),
Switch(
value: autoStart,
onChanged: (value) {
setState(() {
autoStart = value;
});
},
),
],
)
],
),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.autoStart});
final bool autoStart;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey redKey = GlobalKey();
final GlobalKey yellowKey = GlobalKey();
final GlobalKey blueKey = GlobalKey();
final GlobalKey greenKey = GlobalKey();
final MaskGuide maskGuide = MaskGuide();
ScrollController scrollController = ScrollController();
bool canPopOut = true;
Future<void> scrollDown() async {
await scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.linear,
);
}
Future<void> scrollUp() async {
await scrollController.animateTo(
0,
duration: const Duration(milliseconds: 300),
curve: Curves.linear,
);
}
void showMaskGuide({required bool canPop, required bool canDismiss}) {
setState(() {
canPopOut = canPop;
});
maskGuide.showMaskGuide(
context: context,
keys: [redKey, yellowKey, blueKey, greenKey], // 指定目标元素
guideTexts: [
'这是第一个', // 提示文本
'这是第二个',
'这是第三个',
'这是第四个',
],
canPop: canPop, // 是否允许返回键退出
canDismiss: canDismiss, // 是否允许点击遮罩层退出
doneCallBack: () {
setState(() {
canPopOut = true;
});
print('默认完成回调');
},
dismissCallBack: () {
setState(() {
canPopOut = true;
});
print('默认取消回调');
},
nextStepCallBacks: [
() {},
() {},
() => scrollDown(), // 滚动到下一屏
() {},
],
preStepCallBacks: [
() {},
() {},
() {},
() => scrollUp(), // 滚动到上一屏
],
);
}
void showCustomMaskGuide({required bool canPop, required bool canDismiss}) {
setState(() {
canPopOut = canPop;
});
maskGuide.showMaskGuide(
context: context,
keys: [redKey, yellowKey, blueKey, greenKey],
customStepWidget: CustomStepWidget(
keys: [redKey, yellowKey, blueKey, greenKey],
scrollController: scrollController,
), // 自定义步骤小部件
canPop: canPop,
canDismiss: canDismiss,
doneCallBack: () {
setState(() {
canPopOut = true;
});
print('自定义完成回调');
},
dismissCallBack: () {
setState(() {
canPopOut = true;
});
print('自定义取消回调');
},
);
}
[@override](/user/override)
void initState() {
super.initState();
if (widget.autoStart) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => showMaskGuide(canPop: false, canDismiss: false));
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return PopScope(
canPop: canPopOut,
child: Scaffold(
appBar: AppBar(
title: const Text('主页'),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () {
showMaskGuide(canPop: false, canDismiss: false);
},
child: const Text("默认模式,不能取消,不能返回"),
),
ElevatedButton(
onPressed: () {
showMaskGuide(canPop: true, canDismiss: false);
},
child: const Text("默认模式,不能取消,可以返回"),
),
ElevatedButton(
onPressed: () {
showMaskGuide(canPop: false, canDismiss: true);
},
child: const Text("默认模式,可以取消,不能返回"),
),
ElevatedButton(
onPressed: () {
showMaskGuide(canPop: true, canDismiss: true);
},
child: const Text("默认模式,可以取消,可以返回"),
),
ElevatedButton(
onPressed: () {
showCustomMaskGuide(canPop: false, canDismiss: false);
},
child: const Text("自定义模式,不能取消,不能返回"),
),
ElevatedButton(
onPressed: () {
showCustomMaskGuide(canPop: true, canDismiss: false);
},
child: const Text("自定义模式,不能取消,可以返回"),
),
ElevatedButton(
onPressed: () {
showCustomMaskGuide(canPop: false, canDismiss: true);
},
child: const Text("自定义模式,可以取消,不能返回"),
),
ElevatedButton(
onPressed: () {
showCustomMaskGuide(canPop: true, canDismiss: true);
},
child: const Text("自定义模式,可以取消,可以返回"),
),
],
),
const VerticalDivider(),
SingleChildScrollView(
controller: scrollController,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
key: redKey,
width: 50,
height: 50,
color: Colors.red,
),
const SizedBox(height: 200),
Container(
key: yellowKey,
width: 50,
height: 50,
color: Colors.yellow,
),
const SizedBox(height: 200),
Container(
key: blueKey,
width: 50,
height: 50,
color: Colors.blue,
),
const SizedBox(height: 200),
Container(
key: greenKey,
width: 50,
height: 50,
color: Colors.green,
),
],
),
),
],
),
),
),
);
}
}
custom_step_widget.dart
import 'package:flutter/material.dart';
import 'package:mask_guide/mask_guide.dart';
class CustomStepWidget extends StepWidget {
final List<GlobalKey> keys;
final ScrollController scrollController;
CustomStepWidget({
required this.keys,
required this.scrollController,
});
[@override](/user/override)
void preStep() {
super.preStep();
// TODO: 执行一些操作
}
[@override](/user/override)
void nextStep() {
super.nextStep();
// TODO: 执行一些操作
}
[@override](/user/override)
void doneCallBack() {
super.doneCallBack();
// TODO: 执行一些操作
}
}
更多关于Flutter遮罩引导插件mask_guide的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter遮罩引导插件mask_guide的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
mask_guide
是一个用于在 Flutter 应用中实现遮罩引导的插件。它可以帮助你在应用中创建一个带有遮罩的引导层,突出显示特定区域,并提供引导信息。以下是使用 mask_guide
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 mask_guide
插件的依赖:
dependencies:
flutter:
sdk: flutter
mask_guide: ^0.1.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 mask_guide
插件:
import 'package:mask_guide/mask_guide.dart';
3. 使用 MaskGuide
组件
MaskGuide
组件可以包裹在你的应用中的任何部分,用于创建遮罩引导。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:mask_guide/mask_guide.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Mask Guide Example'),
),
body: Center(
child: MaskGuide(
maskColor: Colors.black.withOpacity(0.5),
highlightShape: HighlightShape.circle,
highlightRadius: 50,
highlightOffset: Offset(100, 100),
child: ElevatedButton(
onPressed: () {
print('Button Pressed');
},
child: Text('Click Me'),
),
onMaskTap: () {
print('Mask Tapped');
},
),
),
),
);
}
}
4. 配置 MaskGuide
参数
MaskGuide
组件提供了多个参数来定制遮罩引导的外观和行为:
maskColor
: 遮罩的颜色,通常使用半透明的黑色或白色。highlightShape
: 高亮区域的形状,可以是HighlightShape.circle
或HighlightShape.rectangle
。highlightRadius
: 如果高亮形状是圆形,则指定圆形的半径。highlightOffset
: 高亮区域的偏移量,用于定位高亮区域。onMaskTap
: 当用户点击遮罩时触发的回调函数。
5. 动态显示和隐藏引导
你可以通过控制 MaskGuide
的可见性来动态显示和隐藏引导。例如,使用 Visibility
组件或 AnimatedOpacity
组件来控制 MaskGuide
的显示和隐藏。
bool showGuide = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mask Guide Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Visibility(
visible: showGuide,
child: MaskGuide(
maskColor: Colors.black.withOpacity(0.5),
highlightShape: HighlightShape.circle,
highlightRadius: 50,
highlightOffset: Offset(100, 100),
child: ElevatedButton(
onPressed: () {
setState(() {
showGuide = false;
});
},
child: Text('Click Me'),
),
onMaskTap: () {
setState(() {
showGuide = false;
});
},
),
),
ElevatedButton(
onPressed: () {
setState(() {
showGuide = true;
});
},
child: Text('Show Guide'),
),
],
),
),
);
}
6. 自定义引导内容
你可以在 MaskGuide
中添加自定义的引导内容,例如文本、图标等。通过 overlayBuilder
参数,你可以自定义引导层的内容。
MaskGuide(
maskColor: Colors.black.withOpacity(0.5),
highlightShape: HighlightShape.circle,
highlightRadius: 50,
highlightOffset: Offset(100, 100),
child: ElevatedButton(
onPressed: () {
print('Button Pressed');
},
child: Text('Click Me'),
),
overlayBuilder: (context) {
return Positioned(
top: 150,
left: 50,
child: Text(
'This is a guide!',
style: TextStyle(color: Colors.white, fontSize: 20),
),
);
},
onMaskTap: () {
print('Mask Tapped');
},
);
7. 处理多个引导步骤
如果你需要处理多个引导步骤,可以使用 MaskGuideController
来控制引导的显示顺序。你可以通过 MaskGuideController
来动态切换引导步骤。
MaskGuideController controller = MaskGuideController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mask Guide Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaskGuide(
controller: controller,
maskColor: Colors.black.withOpacity(0.5),
highlightShape: HighlightShape.circle,
highlightRadius: 50,
highlightOffset: Offset(100, 100),
child: ElevatedButton(
onPressed: () {
controller.next();
},
child: Text('Step 1'),
),
overlayBuilder: (context) {
return Positioned(
top: 150,
left: 50,
child: Text(
'Step 1: Click this button',
style: TextStyle(color: Colors.white, fontSize: 20),
),
);
},
onMaskTap: () {
controller.next();
},
),
MaskGuide(
controller: controller,
maskColor: Colors.black.withOpacity(0.5),
highlightShape: HighlightShape.rectangle,
highlightSize: Size(100, 50),
highlightOffset: Offset(100, 200),
child: ElevatedButton(
onPressed: () {
controller.next();
},
child: Text('Step 2'),
),
overlayBuilder: (context) {
return Positioned(
top: 250,
left: 50,
child: Text(
'Step 2: Click this button',
style: TextStyle(color: Colors.white, fontSize: 20),
),
);
},
onMaskTap: () {
controller.next();
},
),
],
),
),
);
}
8. 处理引导结束
当所有引导步骤完成后,你可以通过 MaskGuideController
的 onComplete
回调来处理引导结束的逻辑。
controller.onComplete = () {
print('All steps completed');
};