This is the second part of the Flutter web article series. In the previous article, we finished the basic UI design of the web app and also made it responsive. Now we will add some animations and dark theme support to it as well.
You can find the previous article here:
Flutter Web: Getting started with Responsive Design
Flutter Web has been out there for quite some time, and currently, it is in the Beta stage of Flutter. But it is quite…
Just to refresh your memory, this is what we ended up with last time:
So, let’s get started and make it even better.
We won’t be adding a ton of animations, but just to make the UX of the web app better. Precisely, we will be adding animation to the top bar and the floating selector for cycling through the destinations.
If you have followed along the previous article, then you might have noticed that towards the very end of the article in the final demo the top bar has a nice color transition (from transparent to a shade of blue-gray) as the user scrolls along the webpage. But, I had not covered that part in the previous article.
So let’s see how you can achieve that effect.
You can just vary the opacity of the
backgroundColor of the AppBar according to the user scroll distance. Follow the steps below:
- Define a scroll controller and two more variables for storing the scroll position and opacity:
2. Define a method called
_scrollListener() as follows:
3. Initialize the controller and attach the listener to it.
4. Inside the
build method, calculate the opacity according to the scroll position which depends on the screen height. As we had defined the top image with respect to the screen height, this will help you to determine the precise position after which the opacity should be maximum.
5. Set the opacity to the
backgroundColor of the AppBar, and also pass it to the
PreferredSize widget, which is used for the large screen, to set the color similarly.
In the floating selector, we will add a subtle animation to the underline highlighting the selected destination, while transitioning between different destinations.
You can wrap the Container (used for the underline) with the AnimatedOpacity widget for creating the animation.
You can use a Flutter package called dynamic_theme for adding dynamic theme support to the web app and persist it.
- Add the package to the
2. Wrap the MaterialApp widget with the DynamicTheme widget inside
main.dart file, like this:
3. Define the themes you want to use for the light and dark mode inside the
data property of the DynamicTheme widget:
4. Set the theme of the different widgets according to the properties that you have defined within the ThemeData widget. For example, you can set the background color of the AppBar like this:
I wanted the bottom bar color and the top bar color to be same, so I have defined the color according to the
bottomAppBarColorproperty of the ThemeData.
Almost done, but let’s also talk about a customizable scrollbar.
You might have noticed that the present webpage that we have created doesn’t have a scrollbar, like the one you can see and drag in normal webpages. Flutter Web doesn’t show a scrollbar for a scrollable content by default.
You can display a scrollbar, like you can do in normal mobile apps, by wrapping the whole scrollable content of the webpage with the Scrollbar widget. Thought this might fix the issue for some people, but not in our case.
Turns out that if you have other scrollable content inside your webpage the default
Scrollbarwidget might break.
There’s a caveat in using the Scrollbar widget. It actually picks up every scroll event present in your app (including the nested scrollable widgets), not just the primary one, as you might want for a normal webpage. And, the widget doesn’t come with a property to specify the depth, which you could have used for restricting it only to the primary scroll event.
We have two nested scrollable widgets in our web app, one is the Row wrapped with a SingleChildScrollView (only for small screens) for displaying the feature tiles and the CarouselSlider with the destinations. So, definitely the default Scrollbar wouldn’t work as expected.
How to fix it? You can use the
NotificationListener() widget for getting the depth of the scroll events and only update the Scrollbar if the depth is 0 (primary scroll event is indicated by '0').
Also, the default Scrollbar doesn’t come with any good customization options, like changing the color, width & height of the scrollbar, etc.
So, in order to fix all these issues, I have created a new widget called
It is a StatefulWidget and you can pass the following properties to it:
Let’s take a look at the main part to know how it is created.
First of all, I used the scroll controller, which is passed to this widget, and attached a listener to it.
build method, I have calculated the screen size which is used for setting the scrollbar height with respect to it.
_topMargin variable I have calculated how much of the empty space should be above the scrollbar, basically for setting the position of it. Initially, it is set to zero.
To display the scrollbar, I have used a Stack so that I could place it on top of the child passed to this widget.
For updating the scrollbar with respect to only the primary scroll event, you have to wrap the whole Stack widget with the
NotificationListener() and check for the depth.
You have to define
onVerticalDragUpdate property of the GestureDetector widget in order to update the position of the scrollbar as it is dragged.
Now, just wrap the
SingleChildScrollView widget, containing the whole webpage, with the
WebScrollbar to display it.
So, here you go, now you have a fully customizable scrollbar to use on your webpages.
The whole UI code for the WebScrollbar is available here.
In this article, we covered animations and dynamic theming. In the next article of this series, you will learn how to integrate user registration and sign-in to your Flutter web app using Firebase Authentication.
You can try out the Flutter Web app here.
An article regarding the
How to dynamically change the theme in Flutter
Changing the theme at runtime and persisting those changes across restarts? No problem!
The GitHub repo of this project is available in the following link:
Copyright © 2020 Souvik Biswas Permission is hereby granted, free of charge, to any person obtaining a copy of this…
If you like this project, then please “Star” (⭐️) the GitHub repo.
Check out my other articles
Flutter: Creating an IoT based app to interact with any home electrical equipment
It always looks cool to control any electrical equipment with a mobile device remotely without even going near it.
Flutter: Creating a route calculator using Google Maps
How to integrate Google Maps in Flutter to map a route between two points and calculate its distance.
Flutter: Implementing Google Sign In
In this article, I will be showing how to set up and implement Google Sign In using Firebase Authentication.
If you want to support me and want me to continue writing Flutter articles and building some interesting Flutter projects, please contribute to my Patreon page below:
Souvik Biswas is creating Flutter Apps | Patreon
Become a patron of Souvik Biswas today: Read posts by Souvik Biswas and get access to exclusive content and experiences…