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
TextField
forName
- We will add a new
TextField
forConfirm Password
- We will change the
ElevatedButton
text toRegister
- We will add a
InkWell
widget 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 theLogin
page -
/register
- which will display theRegister
page
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…