🎉 New release for Pusher Chatkit - Webhooks! Extend your in-app chat functionality
Hide
Products
chatkit_full-logo

Extensible API for in-app chat

channels_full-logo

Build scalable realtime features

beams_full-logo

Programmatic push notifications

Developers

Docs

Read the docs to learn how to use our products

Tutorials

Explore our tutorials to build apps with Pusher products

Support

Reach out to our support team for help and advice

Sign in
Sign up

Build an onboarding experience for your mobile apps with Flutter - Part 1: Building the screens

  • Ethiel Adiassa
March 5th, 2019
You will need Dart and Flutter set up on your machine.

Introduction

In this tutorial series, we’ll be building a nice app intro with Flutter exploiting the onboarding technique. Onboarding is a great way to introduce your app to newcomers, to help them quickly adapt to the new conditions so that they can get the most out of your app. In UX design, onboarding is a set of techniques and interactions aimed at comforting users and giving the initial introduction of the product. The Material Design guide states:

Onboarding is one point in a longer journey that begins in the app store and ends with the user taking the first key retention-correlated action in your app.

We can consider onboarding to be a useful UX technique to present your product to potential users, it is defined as a way of making someone familiar with an app. Your apps may not be self-explanatory so they surely need to include onboarding. Now that you know what onboarding is, we’ll dive into this tutorial. I’ll show you how to build a nice onboarding experience for your mobile app using the Flutter framework.

Demo

This is the final result of the tutorial. Nice isn’t it ? 😎 You will be able to achieve that at the end of the tutorial.

Prerequisites

This tutorial assumes a little knowledge of Flutter or Dart. JavaScript knowledge will be helpful as well, especially ES6 features. You should have:

  • Visual Studio Code editor installed on your machine if you haven’t yet. We’ll use it in our tutorial.
  • Visual Studio Code Flutter plugin
  • An emulator or physical device (for app testing/debugging purpose)
  • Flutter and Dart installed on your machine. Kindly refer to this link for more information about their installation. It will guide you through the installation of Flutter SDK on your machine as well as the Dart language

Project setup

Open your code editor and hit ctrl+shift+p or cmd+shift+p to create a new project, and give it a name, or simply run flutter create your_project_name in your terminal to quickly create a new project. After that, you’ll end up with a fresh Flutter project.

Head over to the pubspec.yaml file and amend it like the following:

    //../pubspec.yaml
    name: flutter_slides
    description: A new Flutter project.

    # The following defines the version and build number for your application.
    # A version number is three numbers separated by dots, like 1.2.43
    # followed by an optional build number separated by a +.
    # Both the version and the builder number may be overridden in flutter
    # build by specifying --build-name and --build-number, respectively.
    # Read more about versioning at semver.org.
    version: 1.0.0+1

    environment:
      sdk: ">=2.0.0-dev.68.0 <3.0.0"

    dependencies:
      flutter:
        sdk: flutter
      transformer_page_view:

      # The following adds the Cupertino Icons font to your application.
      # Use with the CupertinoIcons class for iOS style icons.
      cupertino_icons: ^0.1.2

    dev_dependencies:
      flutter_test:
        sdk: flutter


    # For information on the generic Dart part of this file, see the
    # following page: https://www.dartlang.org/tools/pub/pubspec

    # The following section is specific to Flutter.
    flutter:

      # The following line ensures that the Material Icons font is
      # included with your application, so that you can use the icons in
      # the material Icons class.
      uses-material-design: true

      # To add assets to your application, add an assets section, like this:
      assets:
       - assets/slide_1.png
       - assets/slide_2.png
       - assets/slide_3.png
       - assets/slide_4.png
      #  - images/a_dot_ham.jpeg

      # An image asset can refer to one or more resolution-specific "variants", see
      # https://flutter.io/assets-and-images/#resolution-aware.

      # For details regarding adding assets from package dependencies, see
      # https://flutter.io/assets-and-images/#from-packages

      # To add custom fonts to your application, add a fonts section here,
      # in this "flutter" section. Each entry in this list should have a
      # "family" key with the font family name, and a "fonts" key with a
      # list giving the asset and other descriptors for the font. For
      # example:
      fonts:
        - family: Quicksand
          fonts:
            - asset: assets/Quicksand-Bold.ttf
              weight: 700
      #       - asset: fonts/Schyler-Italic.ttf
      #         style: italic
      #   - family: Trajan Pro
      #     fonts:
      #       - asset: fonts/TrajanPro.ttf
      #       - asset: fonts/TrajanPro_Bold.ttf
      #         weight: 700
      #
      # For details regarding fonts from package dependencies,
      # see https://flutter.io/custom-fonts/#from-packages

In the dependencies section of the file, we’ve added the transformer_page_view dependency, a page transformer plugin for Flutter. This will help us to build our onboarding screens with no hassle. Create an assets directory into the root of your Flutter project. You can find the content of this folder at this link.

Don’t forget to run flutter packages get in your terminal to install your dependencies.

Building the onboarding experience

As you may have noticed in the demo, we have four screens, each one has two text views, an image and carousel indicators. These screens present and describe our app to our users in order to make them feel comfortable with it, especially to not make them disoriented. We’ll focus first on building the screens in the first part of the series, as stated in the title

Building the screens

Here’s the code for the screens. Kindly paste it in your main.dart file.

    //..lib/main.dart

    import 'package:flutter/material.dart';
    import 'package:transformer_page_view/transformer_page_view.dart';

    void main() => runApp(MyApp());
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Flutter Demo',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }

    class MyHomePage extends StatefulWidget {
      final String title;
      MyHomePage({this.title});
      @override
      MyHomePageState createState() {
        return new MyHomePageState();
      }
    }

    class MyHomePageState extends State<MyHomePage> {
      int _slideIndex = 0;

      final List<String> images = [
        "assets/slide_1.png",
        "assets/slide_2.png",
        "assets/slide_3.png",
        "assets/slide_4.png"
      ];

      final List<String> text0 = [
        "Welcome in your app",
        "Enjoy teaching...",
        "Showcase your skills",
        "Friendship is great"
      ];

      final List<String> text1 = [
        "App for food lovers, satisfy your taste",
        "Find best meals in your area, simply",
        "Have fun while eating your relatives and more",
        "Meet new friends from all over the world"
      ];

      final IndexController controller = IndexController();

      @override
      Widget build(BuildContext context) {

        TransformerPageView transformerPageView = TransformerPageView(
            pageSnapping: true,
            onPageChanged: (index) {
              setState(() {
                this._slideIndex = index;
              });
            },
            loop: false,
            controller: controller,
            transformer: new PageTransformerBuilder(
                builder: (Widget child, TransformInfo info) {
              return new Material(
                color: Colors.white,
                elevation: 8.0,
                textStyle: new TextStyle(color: Colors.white),
                borderRadius: new BorderRadius.circular(12.0),
                child: new Container(
                  alignment: Alignment.center,
                  color: Colors.white,
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        new ParallaxContainer(
                          child: new Text(
                            text0[info.index],
                            style: new TextStyle(
                                color: Colors.blueGrey,
                                fontSize: 34.0,
                                fontFamily: 'Quicksand',
                                fontWeight: FontWeight.bold),
                          ),
                          position: info.position,
                          opacityFactor: .8,
                          translationFactor: 400.0,
                        ),
                        SizedBox(
                          height: 45.0,
                        ),
                        new ParallaxContainer(
                          child: new Image.asset(
                            images[info.index],
                            fit: BoxFit.contain,
                            height: 350,
                          ),
                          position: info.position,
                          translationFactor: 400.0,
                        ),
                        SizedBox(
                          height: 45.0,
                        ),
                        new ParallaxContainer(
                          child: new Text(
                            text1[info.index],
                            textAlign: TextAlign.center,
                            style: new TextStyle(
                                color: Colors.blueGrey,
                                fontSize: 28.0,
                                fontFamily: 'Quicksand',
                                fontWeight: FontWeight.bold),
                          ),
                          position: info.position,
                          translationFactor: 300.0,
                        ),
                        SizedBox(
                          height: 55.0,
                        ),
                      ],
                    ),
                  ),
                ),
              );
            }),
            itemCount: 4);

        return Scaffold(
          backgroundColor: Colors.white,
          body: transformerPageView,
        );

      }
    }

First, we import the material library so that we can use the MaterialApp widget inside our app. We’ve also imported our transformer_page_view_dependency. Now inside our main function, we have our MyApp widget returning the MaterialApp widget defining our app title, our app theme, and our MyHomePage widget.

The MyHomePage widget is a stateful widget as it has to manage its own state through some data. MyHomePageState is intended to handle the state of MyHomePage as you can see. Then, we defined four variables:

  • _slideIndex: initialized to 0, this variable is used to keep track of the current index of our slide
  • images: an array of images to use in our screens
  • text0 and text1: arrays of texts to describe our screens
  • controller: an object of IndexController to get some useful info about indexes of screens and to control them.

Next, we declared our transformerPageView object of type TransformerPageView to build our well said screens, and to control their behavior. This object has some useful properties to control our page view behavior. We’ll take a look at some of them:

  • onPageChanged: called with the new index when the user swiped, we overrided the _slideIndex with the new current index each time the user swiped
  • loop: whether to loop or not, we set it to false
  • controller: the index controller
  • transformer: the most important property of this widget, it returns a transformed widget that based on the widget parameter. The returned widget as it happens is the current screen presented to the user, just a Material widget wrapping two texts widget and an image asset. We wrapped each of these widgets inside a ParallaxContainer to mimic a parallax effect on screens swiping.
  • itemCount: number of total items/screens.

So here are the four screens you should have if you have followed along 🙃 .

Just execute this command: flutter run in your terminal to run your app running with a smooth transition between screens 😎 .

In the next part of the tutorial, we’ll add carousel indicators to the slides to make it more user friendly.

Conclusion

In this first part of this tutorial series, you’ve learnt what onboarding is, then we’ve put this knowledge into practice by building the screens of our app intro. This is just the first steps of a beautiful journey 😉 . Follow me in the second part to see how we can polish the app with the carousel indicators and get more control over the app. Here is the code for the first part of the series.

Clone the project repository
  • Android
  • Flutter
  • iOS
  • no pusher tech

Products

  • Channels
  • Chatkit
  • Beams

© 2019 Pusher Ltd. All rights reserved.

Pusher Limited is a company registered in England and Wales (No. 07489873) whose registered office is at 160 Old Street, London, EC1V 9BW.