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.
No comments yet…