flutter_intro
一种更好地为您的 Flutter 项目介绍新功能和提供分步用户指南的方法。

用法
要使用此软件包,请将 flutter_intro 添加为 pubspec.yaml 文件中的依赖项。
初始化
import 'package:flutter_intro/flutter_intro.dart';
Intro intro = Intro(
/// The total number of guide pages, must be passed
stepCount: 4,
/// The padding of the highlighted area and the widget
padding: EdgeInsets.all(8),
/// Border radius of the highlighted area
borderRadius: BorderRadius.all(Radius.circular(4)),
/// Use the default useDefaultTheme provided by the library to quickly build a guide page
/// Need to customize the style and content of the guide page, implement the widgetBuilder method yourself
widgetBuilder: StepWidgetBuilder.useDefaultTheme(
/// Prompt text
texts: [
'Hello, I\'m Flutter Intro.',
'I can help you quickly implement the Step By Step guide in the Flutter project.',
'My usage is also very simple, you can quickly learn and use it through example and api documentation.',
'In order to quickly implement the guidance, I also provide a set of out-of-the-box themes, I wish you all a happy use, goodbye!',
],
/// Button label
btnLabel: 'I KNOW',
/// Whether to display the current step after the button
showStepLabel: true,
),
);

将 globalKey 绑定到需要引导的组件
第一个步骤中的 intro 对象包含 keys 属性,而 keys 是一个长度为 stepCount 的 globalKey 数组。只需将数组中的 globalKey 绑定到相应的组件即可。
Placeholder(
/// The first guide page is the first item in the binding keys
key: intro.keys[0]
)
运行
就是这样!
intro.start(context);
自定义 widgetBuilder 方法
如果您需要完全自定义指南页面的样式和内容,则需要自己实现 widgetBuilder 方法。
final Widget Function(StepWidgetParams params) widgetBuilder;
当 intro 页面出现时,flutter_intro 将在内部调用此方法,
并将当前页面的一些数据以 StepWidgetParams 参数的形式传递,
最终在屏幕上渲染此方法返回的组件。
class StepWidgetParams {
/// Return to the previous guide page method, or null if there is none
final VoidCallback onPrev;
/// Enter the next guide page method, or null if there is no
final VoidCallback onNext;
/// End all guide page methods
final VoidCallback onFinish;
/// Which guide page is currently displayed, starting from 0
final int currentStepIndex;
/// Total number of guide pages
final int stepCount;
/// The width and height of the screen
final Size screenSize;
/// The width and height of the highlighted component
final Size size;
/// The coordinates of the upper left corner of the highlighted component
final Offset offset;
}

StepWidgetParams 提供了生成指南页面所需的所有参数。
默认提供的主题也是基于此参数生成指南页面的。
问答
Q1. 如果高亮区域未完全显示怎么办?

A1. 这是因为 Intro 默认提供了 8 像素的内边距。

我们可以通过设置内边距值来更改它。
intro = Intro(
...,
/// Set it to zero
padding: EdgeInsets.zero,
);

Q2. 我可以为每个步骤设置不同的配置吗?
A2. 在 0.4.x 版本以上,您可以通过 setStepConfig 和 setStepsConfig 为单个或多个步骤设置配置(内边距和边框半径)。
intro.setStepConfig(
1,
padding: EdgeInsets.symmetric(
vertical: -5,
horizontal: -8,
),
);
intro.setStepsConfig(
[0, 1],
borderRadius: BorderRadius.all(
Radius.circular(
16,
),
),
);
Q3. 我可以缩小高亮区域吗?
A3. 您可以通过将内边距设置为负数来实现。
intro.setStepConfig(
1,
padding: EdgeInsets.symmetric(
vertical: -10,
horizontal: -8,
),
);

示例
class _MyHomePageState extends State<MyHomePage> {
Intro intro;
_MyHomePageState() {
/// init Intro
intro = Intro(
stepCount: 4,
/// use defaultTheme, or you can implement widgetBuilder function yourself
widgetBuilder: StepWidgetBuilder.useDefaultTheme(
texts: [
'Hello, I\'m Flutter Intro.',
'I can help you quickly implement the Step By Step guide in the Flutter project.',
'My usage is also very simple, you can quickly learn and use it through example and api documentation.',
'In order to quickly implement the guidance, I also provide a set of out-of-the-box themes, I wish you all a happy use, goodbye!',
],
btnLabel: 'I KNOW',
showStepLabel: true,
),
);
}
@override
void initState() {
super.initState();
Timer(Duration(microseconds: 0), () {
/// start the intro
intro.start(context);
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SizedBox.expand(
child: Container(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 100,
child: Placeholder(
/// 2nd guide
key: intro.keys[1],
fallbackHeight: 100,
),
),
SizedBox(
height: 16,
),
Placeholder(
/// 3rd guide
key: intro.keys[2],
fallbackHeight: 100,
),
SizedBox(
height: 16,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
width: 100,
child: Placeholder(
/// 4th guide
key: intro.keys[3],
fallbackHeight: 300,
),
),
],
),
],
),
),
),
floatingActionButton: FloatingActionButton(
/// 1st guide
key: intro.keys[0],
child: Icon(
Icons.play_arrow,
),
onPressed: () {
intro.start(context);
},
),
);
}
}