Pinkesh Darji
Jun 14 · 4 min read
Image Credits: https://www.vecteezy.com Design Credits: https://bit.ly/2VgXF54

User onboarding is a very important feature when you have a bunch of cool feature in your app. It's a process of guiding your users to get more familiar with the app.

Let’s see the final output first.

Pretty cool! Right? So let’s get started.

UI Structure

Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
PageView.builder(...),
Stack(...),
Visibility(...)
],
)

The Stack Widget is the best fit when we need to overlap one widget over other. So in our case, Stack has:

  • PageView.builder() to slide through different screens.
  • Stack() to contain a number of page indicators.
  • Visibility() to hide and show ‘Arrow’ button.

Now let's see each widget in detail.

1) PageView.builder();

Creates horizontal/vertical slidable widget.

First of all, we will need to create a list of widgets. This list may contain different screens that will show up when sliding. It can be created like this

final List<Widget> introWidgetsList = <Widget>[
Screen1(...),
Screen2(...),
Screen3(...),
];

We can also create one common widget/screen and change the images based on passed params. This is optional but good to have.

PageView.builder(
physics: ClampingScrollPhysics(),
itemCount: introWidgetsList.length,
onPageChanged: (int page) {
getChangedPageAndMoveBar(page);
},
controller: controller,
itemBuilder: (context, index) {
return introWidgetsList[index];
},
)

Now we can provide the list details to itemCount and itemBuilder property of PageView.builder. onPageChanged property is used to notify when pages change so that we can show the appropriate page indicator.

2) Stack();

I have used stack but you can use any widget to show page indicators.

Stack(
alignment: AlignmentDirectional.topStart,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 35),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < introWidgetsList.length; i++)
if (i == currentPageValue) ...[circleBar(true)] else
circleBar(false),
],
),
),
],
)

Stack further contains the Row() that aligns the page indicators besides each other and circleBar(true/false) is the actual widget that shows Page indicator or Dot. Using Dart’s 2.3 new feature Collection for and Collection If we can show a number of circleBar() as the number of screens and pass True or False to notify whether isActive.

Let’s have a deeper look inside it.

Widget circleBar(bool isActive) {
return AnimatedContainer(
duration: Duration(milliseconds: 150),
margin: EdgeInsets.symmetric(horizontal: 8),
height: isActive ? 12 : 8,
width: isActive ? 12 : 8,
decoration: BoxDecoration(
color: isActive ? kOrange : klightGrey,
borderRadius: BorderRadius.all(Radius.circular(12))),
);
}

As you can see it’s just AnimatedContainer that changes its height and width and color based on the isActive parameter.

3) Visibility;

This widget controls the visibility of its child, and in our case its Floating action button.

Visibility(
visible: currentPageValue == introWidgetsList.length - 1
? true
: false,
child: FloatingActionButton(
onPressed: () {
},
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(26))),
child: Icon(Icons.arrow_forward),
),
)

FloatingActionButton gets visible only when the last screen is showing up.

Finally here comes the magic.

Here is the implementation for the getChangedPageAndMoveBar that we are calling from onPageChange of PageView.

void getChangedPageAndMoveBar(int page) {
currentPageValue = page;
setState(() {});
}

Setting currentPageValue as of currently displayed screen on PageView and setState(() {}); will do rest of the magic. I would suggest you please try it from here.

That’s it.

I hope you have understood the basic idea of implementing this.

Thanks for reading this article. If you like it, click on 👏 to rate it out of 50 and also share with your friends. It means a lot to me.

For more about programming, follow me and Aubergine Solutions, so you’ll get notified when we write new posts.

Would you like to check out my other articles

Little about me :)

Aubergine Solutions

Among the World’s Top 50 UX Agencies. We’re a team of UX Designers and IT Engineers. We balance our madness and method. To know more about us visit www.auberginesolutions.com

Pinkesh Darji

Written by

Passionate Flutter Dev | Google Certified Associate Android Developer | Cross-platform App Dev | Kotlin Android Dev https://github.com/pinkeshdarji

Aubergine Solutions

Among the World’s Top 50 UX Agencies. We’re a team of UX Designers and IT Engineers. We balance our madness and method. To know more about us visit www.auberginesolutions.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade