# Interactive Tutorial of App for Users | Flutter

## What I meant by interactive demo/tutorial, and it's need

While finishing the app for one of my clients, a problem we encountered was with onboarding the new users and guiding them through all the available features, and giving them a tutorial on those features at the same time. I think creating a demo guide for new users is a crucial part of customer onboarding as it not only introduces users to your app but also gives them insight as to how to use it.

There are two cases where I have found this useful-

* Onboarding new users
    
* Introducing new features/changes for old users
    

## What we are going to achieve

![coachgif.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1667029626501/8aPWIhDMr.gif align="left")

In this article, we are going to achieve the same with the help of a flutter package - [Tutorial Coach Mark](https://pub.dev/packages/tutorial_coach_mark)

## Implementation

I have created a demo guide for the flutter demo counter app that we get on creating a new project.

The widget we want to focus on or highlight during the demo is called a **target**. Each target has to be associated with a global key that will be used to find that widget.

```plaintext
  late TutorialCoachMark tutorialCoachMark;
  GlobalKey counterIconKey = GlobalKey();
  GlobalKey progressKey = GlobalKey();
```

Let's associate the global keys with the widgets that we want to highlight -

```plaintext
//progress text
Text(
        '$_counter',
         key: progressKey,
         style: Theme.of(context).textTheme.headline4,
        )

//action button to increase the progress counter
floatingActionButton: FloatingActionButton(
        key: counterIconKey,
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      )
```

Now let's create a list of targets that we want to focus on -

We will add each target using TargetFocus class. TargetFocus contains an *identify* text, *keyTarget* and the *contents* to display on the screen while highlighting the target.

In *keyTarget*, use the global key associated with the widget that you want to highlight. In *contents*, use builder method of TargetContent class to display flutter widgets on screen at the time that particular widget from app is highlighted. So, in *contents*, you will use widgets to guide the user about the app.

This function will return a list of all the targets.

```plaintext
List<TargetFocus> _createTargets() {
    List<TargetFocus> targets = [];
    targets.add(
      TargetFocus(
        identify: "counterIcon",
        keyTarget: counterIconKey,
        alignSkip: Alignment.topRight,
        contents: [
          TargetContent(
            align: ContentAlign.top,
            builder: (context, controller) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const <Widget>[
                  Text(
                    "Press this button to increase the counter by one",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
    targets.add(
      TargetFocus(
        identify: "progressText",
        keyTarget: progressKey,
        alignSkip: Alignment.topRight,
        contents: [
          TargetContent(
            align: ContentAlign.top,
            builder: (context, controller) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const <Widget>[
                  Text(
                    "You can check the current counter progress here",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                  Text(
                    "Congrats! This is the end of the tutorial. Try pressing the counter icon.",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
    return targets;
  }
```

Now let's create a function to create the tutorial and tie everything together. Here we will define the *tutorialCoachMark* variable that we declared earlier and this will define our entire demo. Use the *\_createTargets* method that we defined earlier to get the list of *TargetFocus* and define the basic properties such as shadow color, opacity and what happens on skipping or finishing the demo.

```plaintext
void createTutorial() {
    tutorialCoachMark = TutorialCoachMark(
      targets: _createTargets(),
      colorShadow: Colors.red,
      textSkip: "SKIP",
      paddingFocus: 10,
      opacityShadow: 0.8,
      onFinish: () {
        print("finish");
      },
      onClickTarget: (target) {
        print('onClickTarget: $target');
      },
      onClickTargetWithTapPosition: (target, tapDetails) {
        print("target: $target");
        print(
            "clicked at position local: ${tapDetails.localPosition} - global: ${tapDetails.globalPosition}");
      },
      onClickOverlay: (target) {
        print('onClickOverlay: $target');
      },
      onSkip: () {
        print("skip");
      },
    );
  }
```

Once this setup is done, call this create tutorial function in *initState* to define the demo and then display it.

```plaintext
  @override
  void initState() {
    createTutorial();
    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
      tutorialCoachMark.show(context: context);
    });
    super.initState();
  }
```

## Note

You can use [shared\_preferences](https://pub.dev/packages/shared_preferences) package or any other condition to make sure that this demo guide is not displayed every time you reload the app.

This is it for this article :) Subscribe to the newsletter for more.
