Cross-Platform Mobile Apps with Flutter

Bottom Navigation

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Cross-Platform Mobile Apps with Flutter

Check out a free preview of the full Cross-Platform Mobile Apps with Flutter course

The "Bottom Navigation" Lesson is part of the full, Cross-Platform Mobile Apps with Flutter course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano uses the BottomNavigationBar widget to add navigation to the bottom of the application. The Material UI library includes a number of icons that can be used in the navigation. The BottomNavigationBar widget has an onTap event that can be used to update the selected index of the navigation and rerender the correct widget in body.


Transcript from the "Bottom Navigation" Lesson

>> So the next step to finish our app is to create the bottom bar navigation with some kind of tabs. So we can actually change sections. We can go from one page to one section to another section, okay? We wanna do the menu page where we can see all the coffees that we are selling, and then the orders page.

So how to work with navigation bars? We need to go back to main now. And by the way, if you're following the companion website, we are now, if I go in to the table of contents, we will do 3.3, Setting up Bottom Navigation. And we're going to create the bottom bar, that's what we're going to do.

So actually, what we need to do is to create into the scaffold option. There is a scaffold widget here, let me rearrange my windows. We have a scaffold, the scaffold widget represents actually some kind of an app user interface that has a top bar, a bottom bar. If you have many things that looks like an app, that's the scaffold widget.

The scaffold, which right now has an app bar, that's actually the top bar and the body, but they can have more arguments. And one of those arguments is bottomNavigationBar, okay? And it can create a bottom navigation bar. That is another widget with many, many properties, such as the items that I'm going to use, okay?

That's like the first time, the first thing that I wanna add there, okay? So what are the items that I need to create there? The item is an array. An array of what? An array of, let me create one so we can actually create the other ones. It's an array of BottomNavigationBarItem.

So it's an object that has the icon and the name, okay, make sense? So we are making the little icons that will appear at the bottom in the tab, okay, make sense? So icons, where should I get the icon from? Of course, I can go and create my own icon, like PNG or whatever.

But Flutter includes automatically an icons gallery, it's a material icons gallery. And we can take the icon from Icons., and we have a large list of icons. Of course, looking at the icons here is kind of, okay, I don't see the icon, okay? These icons are actually part of the Material icons gallery.

It's available at, and here you can search and look for all the icons in this collection. Okay, but if you want, you can use your own icons, your own images. So for example, there is an icon for coffee. So I can create one material with the, and then can have a label.

It's actually the name that will be with it, such as "Menu", okay, like so. So we have one BottomNavigationBarItem, it's complaining about the const as well. So where, in the items, like so. So we have one BottomNavigationBarItem. And the icons, what I'm missing is that I need to wrap the name of the icon within an icon constructor, there we are.

So I need three items of this. I'm going to jump to full screen for a second, so we can actually see all the options. So I have three, Menu, Offers, and Order, or My Order, however you wanna call that. For Offers, we do have one called local_offer, that's one icon.

I have already searched for icons, so I already picked a couple. And for here we can use shopping_cart, there are a couple of shopping_cart, outline, rounded, sharp, you pick the one you prefer, okay? But something like this, I think, will make the trick, so that's my bottom navigation bar.

Remember, if you wanna see these in new lines, the simplest way is to add the trailing comma. You pick the one you prefer, if you wanna do like this, because here we see the constructor in just one line. Remember, this is an array of items. Okay, I can even add a trailing comma here, so then I can go back.

Right now it's not doing anything, because there is an error here, because there is a missing parenthesis. Let me balance this, think this is closing the icon, and not closing the navigation bar, there we are. So now you can see it goes to a new line because it doesn't fit.

So the IDE is smart enough when you do all the format. Because, I mean, the icon name is really large, it doesn't fit in one line, it goes automatically to a second one. Every time you save, it's applying this prettifier system, okay, make sense? Any question at this point?

So let's see what happens within Chrome. Look at the bottom, we have menus. So just by adding an array of icons, the navigation bottom bar appears, it doesn't work, that's the problem. So it's not doing anything, okay? I mean, by default, that's Material Design guidelines, okay? To use the primary color swatch for the selector menu, for the selector icon, that's the same color as we have at the top.

But if we want, we can change that. So, in the bottom navigation, apart from items, we have more properties that we can set. And we have backgroundColor, we have a selectedItemColor. So we can change for the backgroundColor, and say that we want the primary color from our theme, for example.

So we can take the primaryColor, so now it looks like this. But now we need to change the foreground color of the icons, okay? And we have two, we have a selectedItemColor. And I can use a yellow one. Remember we have several versions of several shades of yellow, let's try 400, and unselectedItemColor.

And I can take here from one of the browns, like so. So now it looks better. So we need to make that bottom bar to work, right now it's doing nothing. That's because we'd actually need to do it manually, how? The bottomNavigationBar has two properties, the one property that will let you know exactly, The current index, okay?

That will tell you where we are, for example, if I wanna be in offers, it's actually 1, 0, 1, 2. Let me do this so we can actually see that. So now Offers is selected. And then we have some events, such as onTap. And also we have an event that is actually much better than onTap, but with onTap, typically, it works.

onTap will receive the index as an argument. So with this in mind, we have the currentIndex, we have the active tab index, and we have an event that will give us the new index. What we can do here? What do you think that we can do here to change the selected icon?

Again, we have a variable here for defining the current active tab. And also we have an event that will give us the new index, we need an a state variable. Fortunately, by default, the homepage was in a StatefulWidget. Because it's already in a StatefulWidget, I can create a state variable.

Remember, state variable is a variable that I can change, I will trigger a rerender. So within my state, remember the state is this one, the private class, I can create the property. selectedIndex, selectedTab, so I'm gonna start with 0, with 1, it's up to me. And then, instead of 1, I need to use that property, make sense?

What do I need to do in onTap? Should I directly change the property, Like so? Let's see, I'm changing and nothing happens. Does anyone know why? I'm changing the state. But there was one rule for changing the state, that change must happen within a set a state call.

If not, it will change the variable, but it's not going to reveal the tree. So it's not going to reveal the UI, so I need to call setState. setState has as an argument a function, and I need to put my changes in the function. So now if I change, it's changing.

Does it make sense? Yeah, so that's how we make stateful widgets with a stateful variables that are updating the UI, okay, makes sense? So now we need to change the body of the scaffold. The scaffold has a body that is right now is rendering OffersPage. Well, now, based on, I can do a switch, right?

And actually, based on what we have at the top, I can do something. The problem is that body is a property. I'm actually executing, this is Dart what I'm doing here, what is this? This is a constructor, do you see this? This is a constructor, okay? So I'm constructing a scaffold.

I cannot put a swift or an if within one argument of the scaffold, because that's not an expression. Does it make sense? So maybe what I want is a variable, I wanna render in the body. And I can call it the currentWidgetPage, or something like that. It's a property, a variable that I need to create here.

And I can do the switch to know what to render before the return. Does it make sense? So let's call this the currentWidgetPage. And I can, I mean, just through for playing with this quickly, I can just make a dummy text, Like so, and then I can do a switch.

And based on the selected index, I will render one page or the other. What is a page? A widget, everything is a widget here in Flutter. So if it's 0, by the way, the switch is the same switch as in Java and JavaScript. So if it's 0, I'm going to say that the currentWidgetPage, or the selectedPage, or however you wanna call that variable, it's one that I don't have yet.

But let's say that it's going to be the Menu page, and it's a constant. Okay, makes sense, we need a break. If it's 1, we already have the page for that, remember, it's Offers, the OffersPage widget, break. And if it's 2, it's another one that we don't have, the Orders page, break.

So now, I have an error here, because I need to import offers, because it's in a different file. Quick fix, Let me see, prefer const, okay, I know that you prefer const. The programming that they have here is that this is a text. So it's an implicit type.

The type of the current widget is expecting a text, and I say no, you know what, I'm expecting any kind of widget. Something like that, okay, makes sense? So when you say this, you're saying hey, I don't care about the widget that you're using. Any widget will make the trick, does it make sense?

Now it says, well, maybe we don't need to find a variable, but I will do it again because I'm writing something else. I will do this part again. So what we need to do is we'll define an explicit type, because by default, it's implicitly taking a text. So instead of var, I need to say this is a Widget, any kind of Widget.

And now we have a Menu page, the Offers section, the Order section. So my bottom bar navigation is working. Does it makes sense? This is not the only way to make navigation, in fact, there are some navigators and routing systems more complicated. But for simple to understand solutions, this actually makes the trick.

You can see there are some animation cells at the border if you look there. The icons, they have animations, like the selected one has a little glow animation, everything happens automatically.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now