University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
Licence 3 --- Mobile Applications Practicum
Practical 3: Navigation between screens (Routing)
1) Introduction :
• The aims of this practical are as follows:
To learn how to validate the value entered in a TextField widget.
To define classes representing data models.
To manipulate Navigator class methods to navigate between the
different screens of the "meal_planner" app.
2) Implementation of "DetailsPage" and "AddNewMealPage" trees
widgets:
• In the "screens" folder, create two new files named
"details_page.dart" and "add_new_meal_page.dart". The UI to
implement in these files are represented in Figure 1. In the
"details_page.dart" file, add a Stateless Widget named
"DetailsPage" where the build method is implemented according to
the following tree widgets :
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
• In the same way, in the "add_new_meal_page.dart" file, add a
Stateful Widget named "AddNewMealPage" where the build
method is implemented according to the following tree widgets :
Implement the onPressed function of IconButtons in such a way that
the IconButton add inserts a MyTextField element into the
listOfMyTextField list, and the IconButton delete removes the last
MyTextField in the list if this latter is not empty. Then, each time the
content of the listOfMyTextField list is changed, the setState(){}
should be called to re-build the UI.
3) Validation of entered data:
• Each text field must have a controller of "TextEditingController"
type that recovers user input data at the runtime.
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
• To ensure that all the text field within "LoginPage", "SignupPage"
and "AddNewMealPage" pages have been correctly filled in (ref.
Figure 2), it is necessary to:
a) wrap "Column" widget in a "Form" widget. The latter requires
the "key" parameter of "GlobalKey<FormState>" type. For
instance, "Key: myFormState" where,
GlobalKey <FormState> myFormState = GlobalKey <FormState>();
b) validate the format of the text entered in the text fields "Email",
"Password" and "Confirm password" of the "Signup" page. To
do this, you must use the "myValidator" parameter of the
"MyTextField" widget :
- For instance, for the text field "Email", the parameter
"myValidator" may be implemented as follows:
myValidator: myValidateEmailFct,
String? myValidateEmailFct (String? value) {
const pattern = r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-
/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+";
final regex = RegExp(pattern);
if (value!.isEmpty) { return "Email Can't be empty ";}
else if () { return 'Enter a valid email address';}
return null; }
- For the "Password" text field, it is necessary to check if the
password contains at least one capital letter, one digit and one
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
special character among (@#\&*~). The function
"myValidatePwdFct" is as follows:
String? myValidatePwdFct (String? value) {
const pattern =r'^(?=.*[A-Z])(?=.*?[0-9])(?=.*?[ @#\&*~]) .{8,}';
final regex = RegExp(pattern);
if (value!.isEmpty) { return "Password Can't be empty "; }
else if () { return 'The password must be at least 8
characters \n and should contain at least one upper case, \n one digit,
one special character among (@#\&*~)'; }
return null; }
- Following the same logic, implement "myValidateConfirmPwdFct"
function for "Confirm password" text field. This function aims to
check if the value of "pwdConfirmController" is the same as
"pwdController" value.
myValidator:(value)=> myValidateConfirmPwdFct,(value,[Link]),
- The same applies to "AddNewMealPage" text fields such as
values must not be blank.
c) check if all input values are valid when clicking on "Login",
"Signup" and "Add new meal" buttons. For that, the following
test must be used within the "onPressed :(){...}" parameter of the
three buttons:
If([Link] !.validate())
{print("Valide");} else {print("Not Valide");}
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
4) Data models creation: in the "lib" folder, add a new sub-folder
"models". This latter will contain all data models used in the app.
a) The "Meal" data model: in the "models" folder, add a new
file named "[Link]". In this file, define a class "Meal" that
has three non-optional attributes: "name" and "imgPath" of
type String and "listOfIngredient" of type List<String>. Add
the corresponding constructor.
b) The "DayMeals" data model: in the "models" folder, add a
new file "day_meals.dart". In this file, define a class
"DayMeals" that has two non-optional attributes: "day" of type
String and "listOfMeals" of type List<Meal>. Declare the
corresponding constructor .
5) Navigation (ref. course): the navigation schema is represented in
Figure 3.
a) Simple Navigation: using static navigation.
• In the file "[Link]", add the parameter "routes" to
MaterialApp then define the route for each page
("HomePage", "LoginPage", "SignupPage", "DetailsPage" and
"AddNewMealPage").
• Specify the "home" property of MaterialApp such as
"LoginPage" is the first page displayed when the app starts.
• From "signup" text button of "LoginPage" page, navigate to
"SignupPage" page using pushReplacementNamed method of
Navigator class. The same goes for navigation from
"SignupPage" page to "LoginPage" page through "login" text
button.
• Use the pushNamed method to navigate to "HomePage" page
from "Login" button of the "LoginPage" page.
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
b) Navigation with data passing :
• Modify "DayCard" class to have a single attribute named
"dayAndItsMealsList" of type "DayMeals". This latter will replace
the attribute "day" of type String.
• Make the Icons (visibility and add) clickable by wrapping them in
an "InkWell" Widget. From the "onTap" parameter of these latter,
call the pushNamed method to navigate, respectively, to
"DetailsPage" and "AddNewMealPage".
• To display the list of meals, for a specific day, within the grid of
"DetailsPage" page, it’s necessary to send the "dayAndItsMealsList"
attribute through the "arguments" parameter of the pushNamed
method. This attribute must be recovered from the "DetailsPage"
page as follows:
final receivedData = [Link](context) ?.[Link] as DayMeals ;
List<Meal> myListofMeals = [Link];
This will allow to determine the "mealName" and "imgPath" values
within the "DetailsPage" page:
myListofMeals[index].imgPath;
myListofMeals[index].name
• Pressing the "Add the meal" button of the "AddNewMealPage" page,
should result in the creation of a new object of type "Meal" from the
information entered on the UI fields (textfield controller values).
Then, this object is returned to the "DayCard" widget using the pop
method of the Navigator class.
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
6) Définition du modèle d’entrée:
• Add some images to your project and specify their path in the
"[Link]" file.
• In the "HomePage" page, modify the Dart list "daysList" so that it
contains 7 elements of type "DayMeals" (each element represents a
day of the week with its list of meals), then run the app.
Figure 1 : DetailsPage UI AddNewMealPage UI
University of Tlemcen Abou Bekr Belkaid 2023/2024
Sciences faculty
Computer Science Department
Figure 2 : Input data validation
Figure 3 : Navigation schema