Courses

[NEW] Flutter 3 Mobile App with Laravel 12 API

Adding Registration Form and Navigation

In this lesson, we want to do a few things:

  1. Move our Login page into a separate file
  2. Register Navigation in our app
  3. 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:

  1. We will add a new TextField for Name
  2. We will add a new TextField for Confirm Password
  3. We will change the ElevatedButton text to Register
  4. We will add a InkWell widget to navigate back to the Login page
  5. 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:

  1. /login - which will display the Login page
  2. /register - which will display the Register 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.

Previous: Styling Flutter Forms

No comments yet…

avatar
You can use Markdown