Flutter引导教程插件tuxin_tutorial_overlay2的使用

Flutter引导教程插件tuxin_tutorial_overlay2的使用

tuxin_tutorial_overlay 是一个可以用于教程和引导的 Flutter 包。我在寻找一种更简单的方法来为现有的应用程序添加教程和引导,而无需在应用中嵌入更多的元素。我希望有一个可以作为覆盖层使用的引导,并且能够展示多个背景窗口小部件,允许某些窗口小部件交互,同时禁用其他窗口小部件的交互功能。此外,我还希望能够设置特定形状的孔(如矩形、椭圆形等),因此我创建了这个包。

API

WidgetData.dart

enum WidgetShape { Oval, Rect, RRect }

class WidgetData {
  GlobalKey key;
  WidgetShape shape;
  bool isEnabled;
  double padding;

  WidgetData({
    @required this.key,
    this.shape = WidgetShape.Oval,
    this.isEnabled = true,
    this.padding = 0,
  });
}

你使用它来定义每个窗口小部件的相关属性,比如填充、是否启用(允许用户交互)以及覆盖层中的孔形状。

TutorialOverlayUtil.dart

void createTutorialOverlay({
  @required String tagName,
  @required BuildContext context,
  bool enableHolesAnimation = true,
  bool enableAnimationRepeat = true,
  double defaultPadding = 4,
  List<WidgetData> widgetsData = const [],
  Function onTap,
  Color bgColor,
  Widget description,
  int highlightCount = 3,
  int animationMilliseconds = 150,
  int animationRepeatDelayMilliseconds = 3000,
}) 
  • tagName - 覆盖屏幕的名称,稍后显示时会用到。
  • context - 页面的 BuildContext。
  • enableHolesAnimation - 是否启用可见窗口小部件上的动画以引起注意。
  • enableAnimationRepeat - 是否启用动画重复。
  • defaultPadding - 每个显示窗口小部件的默认填充。
  • widgetsData - 一个列表,包含你想要完全可见的每个窗口小部件及其相关属性(填充、启用/禁用交互和孔形状)。
  • onTap - 用户点击覆盖层时调用的回调函数。
  • bgColor - 自定义背景颜色,默认为黑色,透明度为 0.4。
  • description - 显示在覆盖层顶部的小部件,通常包含当前帧的说明。
  • highlightCount - 高亮动画运行的次数。
  • animationMilliseconds - 动画每个方向(前进、后退)所花费的毫秒数。
  • animationRepeatDelayMilliseconds - 动画重复之前的等待时间(毫秒)。

我还创建了两个函数来显示和隐藏覆盖层。

void showOverlayEntry({String tagName, bool redisplayOverlayIfSameTAgName = true}) async;
void hideOverlayEntryIfExists();
  • showOverlayEntry() 用于显示之前通过 createTutorialOverlay() 创建的覆盖层。
  • hideOverlayEntryIfExists() 用于隐藏覆盖层。

请注意,你需要在元素绘制完成之后再调用 createTutorialOverlay() 函数,以便获取它们正确的位置和大小。在我的示例中,我在 StatefulWidgetinitState() 函数中创建了覆盖层,因此为了让元素先绘制出来,我需要在一个框架回调中执行该函数:

import 'package:flutter/scheduler.dart';

...

[@override](/user/override)
void initState() {
  SchedulerBinding.instance.addPostFrameCallback((_) {
    createTutorialOverlay(
      tagName: 'example',
      ...
    );
    showOverlayEntry(tagName: 'example');
  });

  super.initState();
}

简单示例

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:tuxin_tutorial_overlay2/TutorialOverlayUtil.dart';
import 'package:tuxin_tutorial_overlay2/WidgetData.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tux-In Tutorial Overlay 示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: '教程覆盖示例页面'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  final GlobalKey buttonKey = GlobalKey();
  final GlobalKey counterKey = GlobalKey();
  double _leftPosition = 0;

  [@override](/user/override)
  void initState() {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      createTutorialOverlay(
        context: context,
        tagName: 'example',
        bgColor: Colors.green.withOpacity(0.4), // 可选。默认为黑色,透明度为0.4
        onTap: () => print("TAP"),
        widgetsData: [
          WidgetData(key: buttonKey, isEnabled: true, padding: 4),
          WidgetData(key: counterKey, isEnabled: false, shape: WidgetShape.Rect)
        ],
        description: Text(
          '你好',
          textAlign: TextAlign.center,
          style: TextStyle(decoration: TextDecoration.none),
        ),
      );

      showOverlayEntry(tagName: 'example');
    });

    super.initState();
  }

  void _incrementCounter() {
    setState(() {
      _leftPosition += 10;
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '你已经按下了按钮这么多次:',
            ),
            Padding(
              padding: EdgeInsets.fromLTRB(_leftPosition, 0, 0, 0),
              child: Text(
                '$_counter',
                key: counterKey,
                style: Theme.of(context).textTheme.headline4,
              ),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '增加',
        key: buttonKey,
        child: Icon(Icons.add),
      ),
    );
  }
}

更多关于Flutter引导教程插件tuxin_tutorial_overlay2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter引导教程插件tuxin_tutorial_overlay2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


tuxin_tutorial_overlay2 是一个用于在 Flutter 应用中创建引导式教程的插件。它可以帮助你在应用中显示叠加层,引导用户了解如何使用特定的功能或界面元素。以下是如何使用 tuxin_tutorial_overlay2 插件的基本教程。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 tuxin_tutorial_overlay2 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  tuxin_tutorial_overlay2: ^latest_version

然后运行 flutter pub get 以获取依赖。

2. 导入插件

在你的 Dart 文件中导入 tuxin_tutorial_overlay2 插件。

import 'package:tuxin_tutorial_overlay2/tuxin_tutorial_overlay2.dart';

3. 创建引导步骤

你需要定义一系列引导步骤,每个步骤对应一个需要引导用户了解的界面元素。

List<TutorialStep> tutorialSteps = [
  TutorialStep(
    targetGlobalKey: _button1Key,
    description: "This is the first button you should click.",
    shape: FocusShape.circle,
  ),
  TutorialStep(
    targetGlobalKey: _button2Key,
    description: "This is the second button you should click.",
    shape: FocusShape.roundedRectangle,
  ),
];

在这里,targetGlobalKey 是你要引导用户关注的界面元素的 GlobalKey。你需要为每个目标元素创建一个 GlobalKey

4. 定义 GlobalKey

Widget 树中为需要引导的元素定义 GlobalKey

final GlobalKey _button1Key = GlobalKey();
final GlobalKey _button2Key = GlobalKey();

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Tutorial Overlay Example'),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            key: _button1Key,
            onPressed: () {},
            child: Text('Button 1'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            key: _button2Key,
            onPressed: () {},
            child: Text('Button 2'),
          ),
        ],
      ),
    ),
  );
}

5. 启动引导教程

你可以通过调用 TutorialOverlay.showTutorial 方法来启动引导教程。

void startTutorial(BuildContext context) {
  TutorialOverlay.showTutorial(
    context,
    tutorialSteps,
    onTutorialComplete: () {
      print("Tutorial completed!");
    },
  );
}

你可以在用户首次打开应用或点击某个按钮时调用 startTutorial 方法。

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Tutorial Overlay Example'),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            key: _button1Key,
            onPressed: () {},
            child: Text('Button 1'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            key: _button2Key,
            onPressed: () {},
            child: Text('Button 2'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () => startTutorial(context),
            child: Text('Start Tutorial'),
          ),
        ],
      ),
    ),
  );
}

6. 自定义引导样式

你可以通过 TutorialStepshapedescriptionTextStylefocusColor 等属性来自定义引导的样式。

TutorialStep(
  targetGlobalKey: _button1Key,
  description: "This is the first button you should click.",
  shape: FocusShape.circle,
  descriptionTextStyle: TextStyle(fontSize: 16, color: Colors.white),
  focusColor: Colors.blue.withOpacity(0.5),
),

7. 处理引导完成事件

你可以在 onTutorialComplete 回调中处理引导完成后的逻辑,例如显示一个提示或导航到其他页面。

TutorialOverlay.showTutorial(
  context,
  tutorialSteps,
  onTutorialComplete: () {
    print("Tutorial completed!");
    // 你可以在这里添加引导完成后的逻辑
  },
);

8. 关闭引导教程

如果你想在引导教程进行中手动关闭它,可以调用 TutorialOverlay.hideTutorial 方法。

TutorialOverlay.hideTutorial(context);
回到顶部