Flutter UI Design Tutorial – Flutter Homepage Dashboard UI – 2022

Basics, Flutter Login App, Flutter UI / UX, UI UX

In this flutter UI Design tutorial, we will learn to design a modern Homepage Dashboard UI in a flutter. This Flutter dashboard UI will be divided into multiple segments and cover multiple core flutter design concepts. This dashboard UI tutorial is for all who are new or want to enhance their designing skills in a flutter.

This Dashboard UI tutorial will cover the following points.

  1. Responsive Text and Images
  2. Layouts in Horizontal and Vertical Direction
  3. Card & Chip Designs
  4. Scroll Behaviors
  5. Clean Code
  6. Custom Widgets
  7. Light and Dark Theme
  8. UnBounded Height and Width Errors

and much more…

1 – Project Structure

As we are creating Flutter Login App and at the start of this Course we had learned 2 types of Folder Structures.

Therefore, we are using Feature First Approach and as a Global theme we are using the theme we created in this theme tutorial.

After having basic setup, we will add all the assets and constants respectively. You can get assets from here and updated constants from Flutter Login App Homepage.

Now let’s create a new Feature inside Features Folder and name it whatever you like (Core in our case).

Inside Core folder add a new dart file called dashboard.dart and folder called widgets (for local widgets).

2 – Flutter Appbar

Inside our dashboard.dart create a StateLess Widget by simple writing stless and hit enter.

Name the Statless class as DashboardScreen

Wrap the Container widget with Scaffold to apply Material design and to create appbar.

To design a modern and minimal Appbar in Flutter and to make it reusable component, we have to convert it into seprate Custom Widget.

But first, let’s design the appbar in this Dashboard.

This appbar contains 3 items.

  1. Leading Icon (Menu Icon Button)
  2. Title(Center as True)
  3. Action(Profile Icon Button)
AppBar(
      elevation: 0,
      centerTitle: true,
      backgroundColor: Colors.transparent,
      leading: Icon(
        Icons.menu,
        //For Dark Color
        color: isDark ? tWhiteColor : tDarkColor,
      ),
      title: Text(tAppName, style: Theme.of(context).textTheme.headline4),
      actions: [
        Container(
          margin: const EdgeInsets.only(right: 20, top: 7),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            //For Dark Color
            color: isDark ? tSecondaryColor : tCardBgColor,
          ),
          child: IconButton(onPressed: () {}, icon: const Image(image: AssetImage(tUserProfileImage))),
        )
      ],
    ),

3 – Search Bar Flutter

There are many types of search designs that commonly created in Flutter Homepages like Search Icon in AppBar, Search TextField at the top of Flutter Homepage, and clickable Search Box Design that will lead to open a search in new screen.

So, we will follow the last one which is modern and being used widely in professional apps.

To create this design, we need a ROW and inside we have 2 items (Text and Icon).

Whereas the left Border will be created using Container Widget (left border). To add the space between Text(Search…) and Icon, we will use row(mainAxisAlignment as spaceBetween()).

Container(
      decoration: const BoxDecoration(border: Border(left: BorderSide(width: 4))),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(tDashboardSearch, style: txtTheme.headline2?.apply(color: Colors.grey.withOpacity(0.5))),
          const Icon(Icons.mic, size: 25),
        ],
      ),
    ),

4 – Scrollable Categories

To create a scrollable cards as categories, we will use ListView.builder() with direction as horizontal.

Firstly, we will design a Card using Row with a Container as first child and Column as 2nd Child. Column will further contain 2 Texts.

After creating design card or chip, we will convert it into ListView and afterwards, convert it into ListView.builder().

In ListView.builder() we will get the dummy data from a model.

SizedBox(
      height: 45,
      child: ListView.builder(
        itemCount: list.length,
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemBuilder: (context, index) => GestureDetector(
          onTap: list[index].onPress,
          child: SizedBox(
            width: 170,
            height: 45,
            child: Row(
              children: [
                Container(
                  width: 45,
                  height: 45,
                  decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: tDarkColor),
                  child: Center(
                    child: Text(list[index].title, style: txtTheme.headline6?.apply(color: Colors.white)),
                  ),
                ),
                const SizedBox(width: 5),
                Flexible(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(list[index].heading, style: txtTheme.headline6, overflow: TextOverflow.ellipsis),
                      Text(list[index].subHeading, style: txtTheme.bodyText2, overflow: TextOverflow.ellipsis)
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    ),

5 – Banner Design

Banners are of many designs but the reason to design this type of banner is to keep design professional and make it easy to use for any type of app.

This banner design will contain 2 cards and 1 button.

We will divide the design into half using Row and inside 2 Expanded Widgets(to cover equal space).

@override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        //1st banner
        Expanded(
          child: Container(
            decoration: BoxDecoration(borderRadius: BorderRadius.circular(10),
              //For Dark Color
              color: isDark ? tSecondaryColor : tCardBgColor,
            ),
            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: const [
                    Flexible(child: Image(image: AssetImage(tBookmarkIcon))),
                    Flexible(child: Image(image: AssetImage(tBannerImage1))),
                  ],
                ),
                const SizedBox(height: 25),
                Text(tDashboardBannerTitle1, style: txtTheme.headline4, maxLines: 2, overflow: TextOverflow.ellipsis),
                Text(tDashboardBannerSubTitle, style: txtTheme.bodyText2, maxLines: 1, overflow: TextOverflow.ellipsis),
              ],
            ),
          ),
        ),
        const SizedBox(width: tDashboardCardPadding),
        //2nd Banner
        Expanded(
          child: Column(
            children: [
              //Card
              Container(
                decoration: BoxDecoration(borderRadius: BorderRadius.circular(10),
                  //For Dark Color
                  color: isDark ? tSecondaryColor : tCardBgColor,
                ),
                padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: const [
                        Flexible(child: Image(image: AssetImage(tBookmarkIcon))),
                        Flexible(child: Image(image: AssetImage(tBannerImage2))),
                      ],
                    ),
                    Text(tDashboardBannerTitle2, style: txtTheme.headline4, overflow: TextOverflow.ellipsis),
                    Text(tDashboardBannerSubTitle, style: txtTheme.bodyText2, overflow: TextOverflow.ellipsis),
                  ],
                ),
              ),
              const SizedBox(height: 5),
              SizedBox(
                width: double.infinity,
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 10),
                  child: OutlinedButton(onPressed: () {}, child: const Text(tDashboardButton)),
                ),
              )
            ],
          ),
        ),
      ],
    );
  }

6 – Top Courses

This section can be utilized to create any type of Top Items, Courses, Top Products, and anything that suits.

We will create a SizedBox with specific width and height because we cannot cover it using Expanded to make it unbounded.

Then inside a Sizedbox create a Container.

Container will have a BoxDecoration with border Radius and background Color.

Create 2 rows inside it and each contain 2 items.

First Row will have 1 text and 1 Image whereas, 2nd row will have 1st ElevatedCircular Button and 2nd will have Column with 2 texts.

SizedBox(
      height: 200,
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: list.length,
        itemBuilder: (context, index) => GestureDetector(
          onTap: list[index].onPress,
          child: SizedBox(
            width: 320,
            height: 200,
            child: Padding(
              padding: const EdgeInsets.only(right: 10, top: 5),
              child: Container(
                decoration: BoxDecoration(borderRadius: BorderRadius.circular(10),
                  //For Dark Color
                  color: isDark ? tSecondaryColor : tCardBgColor,
                ),
                padding: const EdgeInsets.all(10),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Flexible(
                          child: Text(
                            list[index].title,
                            style: txtTheme.headline4,
                            maxLines: 2,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        Flexible(child: Image(image: AssetImage(list[index].image), height: 110)),
                      ],
                    ),
                    Row(
                      children: [
                        ElevatedButton(
                          style: ElevatedButton.styleFrom(shape: const CircleBorder()),
                          onPressed: () {},
                          child: const Icon(Icons.play_arrow),
                        ),
                        const SizedBox(width: tDashboardCardPadding),
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              list[index].heading,
                              style: txtTheme.headline4,
                              overflow: TextOverflow.ellipsis,
                            ),
                            Text(
                              list[index].subHeading,
                              style: txtTheme.bodyText2,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ],
                        )
                      ],
                    )
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    )

6 – Clean Code

So far we were creating everything inside dashboard.dart but at the end you will see our code size has increased alot and become unmanageable.

Therefore, we have to convert our code into separate Custom widgets.

Let's Connect

Videos are always a better source for in-depth knowledge. So, connect with me at YouTube.

Download Project

Flutter Login App UI Source Code- How to Create a complete Flutter app - Flutter education app - Flutter app UI Design - Flutter Course - Flutter Complete App 2022
Dashboard Source COde - Dashboard design in flutter - flutter dashoard - flutter app design 2022 - Flutter UI - Flutter homepage

Latest Courses

Flutter Login App UI Source Code- How to Create a complete Flutter app - Flutter education app - Flutter app UI Design - Flutter Course - Flutter Complete App 2022
Learn flutter from scratch in 4 hours - Flutter Crash Course - Coding with T

Latest Tutorials

Flutter Profile page UI Design - Flutter app design 2023 - Profile Screen Flutter UI - Flutter 2023
Flutter Firebase phone authentication - Firebase Phone auth tutorial in flutter - Flutter Firebase phone number authentication 2022
Firebase Authentication in flutter - Flutter firebase authentication 2022 - firebase auth tutorial 2022 - firebase flutter auth
How to setup firebase in flutter 2022 - Flutter firebase setup
Dashboard Source COde - Dashboard design in flutter - flutter dashoard - flutter app design 2022 - Flutter UI - Flutter homepage

Join Our Mailing List

Join our mailing list to receive the latest, Free Courses, Video Tutorials, free codes and updates regarding Tutorials and services. You will also start getting coupons on the related services.

You have Successfully Subscribed!

FLUTTER APP

Learn Flutter App development from scratch. Create LOGIN APP that can be used with any application which requires Login Sign Up functionality.

You can watch it on YouTube or read and get source code from Blog Post.

You have Successfully Subscribed!