In this lesson, we want to do a few things:
- Move our Login page into a separate file
- Register Navigation in our app
- Create a Registration page
Once we have done this, we should have interactable Screens (pages) in our app.
Note: We are still missing functionality.


Move the Login Page Into a Separate File
So far, we have written our code in lib/main.dart. This is not a good practice as our code will grow and become hard to manage. We should separate our code into different files.
Luckily, Flutter makes it easy to do this. We can create a new file in the lib directory and move our code into that file.
To make this first modification, we have to copy all the code in lib/main.dart and paste it into a new file while also adding another element—the InkWell widget—to navigate to the Registration page.
lib/screens/auth/Login.dart
import 'package:flutter/material.dart'; class Login extends StatelessWidget { const Login({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Login'), ), body: Container( color: Theme.of(context).primaryColor, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Card( elevation: 0, margin: EdgeInsets.only(left: 20, right: 20), child: Padding( padding: EdgeInsets.all(20.0), child: Column( children: <Widget>[ TextField( keyboardType: TextInputType.emailAddress, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Email', ), ), SizedBox(height: 20), // Acts as a spacer TextField( keyboardType: TextInputType.visiblePassword, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password', ), ), SizedBox(height: 20), // Acts as a spacer ElevatedButton( onPressed: () { print('Login button pressed'); }, child: Text('Login'), style: ElevatedButton.styleFrom( backgroundColor: Colors.purple, foregroundColor: Colors.white, minimumSize: Size(double.infinity, 40), ), ), Padding( /// padding: EdgeInsets.only(top: 20), // Different way to add padding child: InkWell( child: Text('Register new User'), onTap: () => Navigator.pushNamed(context, '/register') ), )/// ], ), ), ) ], ))); }}
Once that is done, we can import the Login class into lib/main.dart and use it. But first, let's create a new file for our Registration page.
Adding Registration Page
Now, we will focus on creating a new file for our Registration page. This file will be based on the Login page we just created but with a few modifications:
- We will add a new
TextFieldforName - We will add a new
TextFieldforConfirm Password - We will change the
ElevatedButtontext toRegister - We will add a
InkWellwidget to navigate back to the Login page - We will use
Navigator.pop(context)to navigate back to the Login page - more on that in a bit.
Let's create a new file in the lib/screens/auth directory called Register.dart and add the following code:
lib/screens/auth/Register.dart
import 'package:flutter/material.dart'; class Register extends StatelessWidget { const Register({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Register'), ), body: Container( color: Theme.of(context).primaryColor, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Card( elevation: 0, margin: EdgeInsets.only(left: 20, right: 20), child: Padding( padding: EdgeInsets.all(20.0), child: Column( children: <Widget>[ TextField( keyboardType: TextInputType.name, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Name', ), ), SizedBox(height: 20), // Acts as a spacer TextField( keyboardType: TextInputType.emailAddress, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Email', ), ), SizedBox(height: 20), // Acts as a spacer TextField( keyboardType: TextInputType.visiblePassword, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password', ), ), SizedBox(height: 20), // Acts as a spacer TextField( keyboardType: TextInputType.visiblePassword, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Confirm Password', ), ), SizedBox(height: 20), // Acts as a spacer ElevatedButton( onPressed: () { print('Login button pressed'); }, child: Text('Login'), style: ElevatedButton.styleFrom( backgroundColor: Colors.purple, foregroundColor: Colors.white, minimumSize: Size(double.infinity, 40), ), ), Padding( padding: EdgeInsets.only(top: 20), // Different way to add padding child: InkWell( child: Text('<- Back to Login'), onTap: () => Navigator.pop(context) ), ) ], ), ), ) ], ))); }}
Once this is done, we can register our pages in our app.
Register Navigation in our App
To register our pages in our app, we need to modify the MaterialApp widget in lib/main.dart to include our pages:
Note: You can copy the code and replace the whole lib/main.dart file.
import 'package:flutter/material.dart';import 'package:laravel_api_flutter_app/Screens/Auth/Login.dart';import 'package:laravel_api_flutter_app/Screens/Auth/Register.dart'; void main() { runApp(MyApp());} class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Login(), routes: { '/login': (context) => Login(), '/register': (context) => Register(), }, ); }}
In this case, we can see that we no longer have a child parameter on our MaterialApp. Instead, our app has the routes parameter, a Map of routes. The key is the route name, and the value is the widget to display.
In this case, we have two routes:
-
/login- which will display theLoginpage -
/register- which will display theRegisterpage
With these routes registered, our Navigation is working. But how do we interact with it?
Visiting Registration Page from Login
To visit the Registration page from the Login page, we have added a small InkWell widget to the Login page. This widget will navigate to the Registration page when clicked.
Padding( padding: EdgeInsets.only(top: 20), child: InkWell( child: Text('Register new User'), onTap: () => Navigator.pushNamed(context, '/register') ),)
This code takes context from our build method and uses Navigator.pushNamed to navigate to the /register route. This is the same as clicking a link in a web browser.
Navigating Back to the Login Page
To navigate back to the Login page from the Registration page, we have added a small InkWell widget to the Registration page. This widget will navigate back to the Login page when clicked.
Padding( padding: EdgeInsets.only(top: 20), child: InkWell( child: Text('<- Back to Login'), onTap: () => Navigator.pop(context) ),)
This code takes context from our build method and uses Navigator.pop to navigate back to the previous page. This is the same as clicking the back button in a web browser.
That's it for our simple Navigation implementation. It acts similarly to our routes and web browser navigation.
Next, we will build our first non-authentication-based page - Categories list.
Check out the GitHub Commit for this lesson.
No comments yet…