Courses

[NEW] Flutter 3 Mobile App with Laravel 12 API

Adding Bottom Navigation Bar

Until now, we constantly moved around our Home and CategoriesList widgets to see some changes. Let's build a navigation bar to have a better user experience:


Reset Our Home Page

Let's revert our Last lesson change from Categories List to Home:

lib/main.dart

// ...
return MultiProvider(
child: MaterialApp(title: 'Welcome to Flutter', routes: {
'/': (context) {
final authProvider = Provider.of<AuthProvider>(context);
return authProvider.isAuthenticated ? CategoriesList() : Login();
return authProvider.isAuthenticated ? Home() : Login();
},

Add Logout to Our Authentication Provider

Since one of our buttons will be a Logout button, let's add a logout method to our AuthProvider:

lib/providers/auth_provider.dart

// ...
 
Future<void> logout() async {
token = '';
isAuthenticated = false;
notifyListeners();
}
 
// ...

The keen eye might see that we don't call any API to destroy the token. This could be an excellent exercise for you to do on your own. We will now remove the token (set it to '').


Add Navigation Bar

Now, we are ready to add our bottom navigation bar. For this, open your home.dart file, and let's modify it:

1. Changing From StateLess to StateFull

lib/screens/home.dart

import 'package:laravel_api_flutter_app/providers/auth_provider.dart';
import 'package:laravel_api_flutter_app/screens/categories/categories_list.dart';
import 'package:laravel_api_flutter_app/screens/transactions/list.dart';
import 'package:provider/provider.dart';
 
// ...
 
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
 
class _HomeState extends State<Home> {
int selectedIndex = 0;
List<Widget> widgetOptions = [Transactions(), CategoriesList()];
 
class Home extends StatelessWidget {
// ...

2. Adding Bottom Navigation Bar

Using the BottomNavigationBar widget, we can add a bottom navigation bar to our application. Inside, we'll add three tabs: Transactions, Categories, and Logout:

lib/screens/home.dart

// ...
 
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
 
appBar: AppBar(
title: Text('Logged in!'),
),
body: Center(
child: Text('Welcome',
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold)),
body: widgetOptions.elementAt(selectedIndex),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4,
child: OverflowBox(//
maxHeight: double.infinity,
child: BottomNavigationBar(
backgroundColor: Theme.of(context).primaryColor.withAlpha(0),
elevation: 0,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet),
label: 'Transactions'),
BottomNavigationBarItem(
icon: Icon(Icons.category), label: 'Categories'),
BottomNavigationBarItem(
icon: Icon(Icons.logout), label: 'Log out')
],
currentIndex: selectedIndex,
onTap: onItemTapped,
),
),//
 
),
),
);
}

3. Adding onItemTapped Method

This method will be responsible for changing the selected tab and logging out the user:

lib/screens/home.dart

// ...
 
Future<void> onItemTapped(int index) async {
if (index == 2) {
final AuthProvider provider =
Provider.of<AuthProvider>(context, listen: false);
await provider.logout();
} else {
setState(() {
selectedIndex = index;
});
}
}
 
}
 

Here's how your home.dart file should look like:

lib/screens/home.dart

import 'package:flutter/material.dart';
import 'package:laravel_api_flutter_app/providers/auth_provider.dart';
import 'package:laravel_api_flutter_app/screens/categories/categories_list.dart';
import 'package:laravel_api_flutter_app/screens/transactions/list.dart';
import 'package:provider/provider.dart';
 
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
 
class _HomeState extends State<Home> {
int selectedIndex = 0;
List<Widget> widgetOptions = [Transactions(), CategoriesList()];
 
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
body: widgetOptions.elementAt(selectedIndex),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4,
child: OverflowBox(
maxHeight: double.infinity,
child: BottomNavigationBar(
backgroundColor: Theme.of(context).primaryColor.withAlpha(0),
elevation: 0,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet),
label: 'Transactions'),
BottomNavigationBarItem(
icon: Icon(Icons.category), label: 'Categories'),
BottomNavigationBarItem(
icon: Icon(Icons.logout), label: 'Log out')
],
currentIndex: selectedIndex,
onTap: onItemTapped,
),
),
),
),
);
}
 
Future<void> onItemTapped(int index) async {
if (index == 2) {
final AuthProvider provider =
Provider.of<AuthProvider>(context, listen: false);
await provider.logout();
} else {
setState(() {
selectedIndex = index;
});
}
}
}

Add Transaction Dummy Page

Last, we need to create a dummy page for our Transactions Tab:

lib/screens/transactions/list.dart

import 'package:flutter/material.dart';
 
class Transactions extends StatefulWidget {
@override
_TransactionsState createState() => _TransactionsState();
}
 
class _TransactionsState extends State<Transactions> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Transactions'),
),
body: Center(
child: Text(
'Coming soon',
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold)
),
),
),
);
}
}

From here, we can load our application, log in and see the bottom navigation bar:

You should be able to switch between the Transactions and Categories tabs:


We will add our Login token to device storage in the next lesson. This will allow us to keep the user logged in even after the app is closed or restarted.


Check out the GitHub Commit for this lesson.

Previous: Using API Authentication Tokens

No comments yet…

avatar
You can use Markdown