Flutter Onboarding Screen ( App Intro Screen ) with Material UI

Flutter Material Onboarding Screen UI Android IOS

The onboarding Screen is one of the most popular that you can see in most of the apps after loading the Splash Screen. The onboarding Screen gives a short overview of an app. Onboarding is simply configuring the app to work for the first time, it can very easily become a boring process. In this article, we are going to see how to implement an Onboarding Screen with a custom UI in Flutter App.

First, add the image that you will be using in the assets section of the pubspec.yaml file.

 assets:
      - assets/
      - assets/intro.png
      - assets/intro1.png
      - assets/intro2.png

Now, follow the steps to implement On Boarding Screen in our Flutter app: 

Start by creating a new Flutter project in either of VS Code or Android Studio. Replace the Flutter default counter application in main.dart with your own stateful widget.

You should have something like this:

import 'package:flutter/material.dart';
import 'package:intro_app_custom_ui/screens/welcome/welcome.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Welcome(),
    );
  }
}

Before Create Welcome stateful widget create content.dart file in welcome folder, then inside of it with the following code:


class UnbordingContent{
  String image;
  String title;
  String discription;
  UnbordingContent({required this.image, required this.title, required this.discription });
}
List<UnbordingContent> contents = [
    UnbordingContent(
      image: "assets/intro.png",
      title: "First slider",
      discription: "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    ),
    UnbordingContent(
        image: "assets/intro1.png",
        title: "Second slider",
        discription: "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    ),
    UnbordingContent(
        image: "assets/intro2.png",
        title: "Three slider",
        discription: "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    )
];


An UnbordingContent is a constant array which have sample data to show the onboarding screen, you can change title, image and description here as per you want in your application.


This is what our main.dart file looks like currently. Now, create a new dart file and name it welcome.dart in welcome folder,  then create the Welcome stateful widget inside of it with the following code:


import 'package:flutter/material.dart';
import 'package:intro_app_custom_ui/screens/welcome/content.dart';


class Welcome extends StatefulWidget{
  @override
  _WelcomeState createState() => _WelcomeState();
}
class _WelcomeState extends State<Welcome>{
  int currentIndex = 0;
  late PageController _controller;
  @override
  void initState() {
    _controller = PageController(initialPage: 0);
    // TODO: implement initState
    super.initState();
  }
  void gotoPage(){
    print("Thankyou");
  }
  @override
  void dispose() {
    _controller.dispose();
    // TODO: implement dispose
    super.dispose();
  }
  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Column(
        children: [
          Align(
            alignment: Alignment.center,
            child: SafeArea(
              left: true,
              top: true,
              right: true,
              bottom: true,
              minimum: const EdgeInsets.all(16.0),
              child: Text("DevHubSpot", style: TextStyle(color: Colors.pinkAccent[700], fontSize: 40, fontWeight: FontWeight.w600),),
            ),
          ),
          Expanded(
              child: PageView.builder(
                controller: _controller,
                itemCount: contents.length,
                onPageChanged: (int index){
                  setState(() {
                    currentIndex = index;
                  });
                },
                itemBuilder: (_, i){
                  return Padding(
                    padding: const EdgeInsets.only(top: 20, left: 60, right: 60, bottom: 40),
                    child: Column(
                      children: [
                        Image.asset(
                          contents[i].image, height: 300,
                        )
                      ],
                    ),
                  );
                },
              )
          ),
          Container(
            height: 300.0,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.vertical(top:Radius.circular(50)),
              color: Colors.pinkAccent[700]
            ),
            child: new Column(
              children: [
                new Expanded(
                  flex: 5,
                  child: Padding(
                    padding: const EdgeInsets.only(top:50, left: 20, right: 20, bottom: 20),
                    child: Column(
                      children: [
                        Text(
                          contents[currentIndex].title,
                          textAlign: TextAlign.center,
                          style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white),
                        ),
                        SizedBox(height: 20,),
                        Text(
                          contents[currentIndex].discription,
                          textAlign: TextAlign.center,
                          style: TextStyle(fontSize: 18, color: Colors.grey[100]),
                        ),
                      ],
                    ),
                  ),
                ),
                new Expanded(
                  flex: 4,
                  child: Container(
                    alignment: Alignment.bottomCenter,
                    child: SafeArea(
                      left: true,
                      top: true,
                      right: true,
                      bottom: true,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children:<Widget> [
                          Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              MaterialButton(
                                minWidth: 50,
                                onPressed: () {
                                  gotoPage();
                                },
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Text("Skip", style: TextStyle(color:Colors.white70, fontSize: 18.0, fontWeight: FontWeight.w500),)
                                  ],
                                ),
                              )
                            ],
                          ),
                          Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: List.generate(
                              contents.length, (index) => buildDot(index, context),
                            ),
                          ),
                          Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              MaterialButton(
                                minWidth: 50,
                                onPressed: () {
                                  if(currentIndex == contents.length-1){
                                    gotoPage();
                                  }else{
                                    _controller.animateToPage(currentIndex+1, duration: Duration(milliseconds: 250), curve: Curves.linear);
                                    setState(() {
                                      currentIndex = currentIndex+1;
                                    });
                                  }
                                },
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Text(
                                      currentIndex == contents.length-1 ? "Done":"Next", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600, fontSize: 18),
                                    )
                                  ],
                                ),
                              )
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
        ],
      )
    );
  }
  Container buildDot(int index, BuildContext context){
    return Container(
      height: 10,
      width: currentIndex == index ? 25 :10,
      margin: EdgeInsets.only(right: 5),
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20),
          color: Colors.white
      ),
    );
  }
}


PageView

A PageView allows the user to swipe between different screens in your app. All you need to set it up are a PageViewController which is a required property of the PageView. Each or widget to be swiped is wrapped inside a list of Widget as children.

Initializing PageController

Inside the stateful widget create controller variable whose type is of PageViewController and another int variable to hold the current index of the page


int currentIndex = 0;
late PageController _controller;

Initialize the state, add the following code after declaring of the page controller’s variable


 @override
  void initState() {
    _controller = PageController(initialPage: 0);
    // TODO: implement initState
    super.initState();
  }

Also, the controller needs to be disposed of, to do this add the following code after the last previous one


@override
  void dispose() {
    _controller.dispose();
    // TODO: implement dispose
    super.dispose();
  }

Adding Indicators

It is common in different application with onboarding screens to see indicators to which screen is currently viewed. The PageView has provision for a function which listen to the change in screen and return the index of the current screen.


Container buildDot(int index, BuildContext context){
    return Container(
      height: 10,
      width: currentIndex == index ? 25 :10,
      margin: EdgeInsets.only(right: 5),
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20),
          color: Colors.white
      ),
    );
  }

Output:






Flutter Material Onboarding Screen UI Android IOS
Comments

AdBlock Detected!

Our website is made possible by displaying ads to our visitors. Please supporting us by whitelisting our website.