Step By Step Tutorial In Learning Flutter: Lesson 05— Creating New Screens
Today, we will be adding new functionality to our Pokemon application. Pretty excited on how we will be adding new screens to each of our Pokedex. We will be learning how to do it as we go step by step. So follow me :)
Below will the final end goal for this lesson
Then it will be the same for the other items. We will just change the title to represent which Pokedex was clicked.
So let us start
Copy the previous lesson 4
Rename it to lesson05_creating_new_screens
Open Android Studio then open the lesson05_creating_new_screens
Refactor and Rename
Rename it to lesson05_creating_new_screens, click OK button
Then, Refactor below too, then click Rename
Rename module, click OK
Put in lesson05_creating_new_screens_android then click OK
Change below the description as highlighted in yellow below
Then, close the pubspec.yaml by clicking the x button on the tab
The above instructions are discussed in depth on the my previous lesson Renaming Project and Module in Android Studio
Then, if you receive similar below, press Get dependencies
You will see below on the Terminal window
We can now proceed by choosing a device emulator to run it
Yours may be different, but you can choose which ever you have in there
Then, on the main.dart
Then, let us Run it by clicking the Green Arrow button
Now, the screen should be updated
The backbone of a new screen will be like this
class YourDescriptiveScreenName extends StatelessWidget {
@override
Widget build(BuildContext context) {
return
}
}
We will now make some adjustments with our screens here
Looking at the diagram below, the Pokemon will be our Main Screen, then it can branch to either Electric Pokemon screen or Fire Pokemon screen
Since our first screen will be where our Drawer (Items) menus are, we will move the lines of code to a separate class
Okay, from the main.dart let us create a skeletal of new screen for our MainScreen
Add below code at the very end of the existing code
//Our Main Screen that holds the menus / items
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return
}
}
Now let us move the content
Highlight starting at Scaffold (from the main.dart)
Until to the ), //Scaffold
Cut it (Control+X)
Then add a semicolon at the end as shown below
The code for our MainScreen will be
//Our Main Screen that holds the menus / items
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
//leading: new Icon(Icons.menu),
titleSpacing: 0.0,
title:
Text('Pokemon'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () {
// do something
},
),
],
),
body: Center(
child: Text('This is the fifth lesson in Flutter'),
),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('POKEDEX'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Electric'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Fire'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Grass'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Ice'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Water'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
)
}
}
Now, let us fix the part of the code where we cut codes earlier
Remove home:
After removing the line for home:
Replace it with below code
// Start the app with the "/" named route. In this case, the app starts
// on the MainScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the MainScreen widget.
'/': (context) => MainScreen(),
},
Now Run the application
The MainScreen will be displayed as shown below
Let us explore what is happening here
We created a screen MainScreen (moving the existing code to a separate class)
Then, we add the line intialRoute where ‘/’ will be the parent (the main)
Then, we add routes defining ‘/’ where to go, in this case MainScreen()
Next, if you will notice, our aim is when we click Electric or Fire or anything from the Drawer we should have a new screen, this hasn’t done yet
Okay, now let’s create a new screen, remember the skeleton in building a new screen? No worries here it is again
class YourDescriptiveScreenName extends StatelessWidget {
@override
Widget build(BuildContext context) {
return
}
}
So having that in mind, let us adopt above an create our first Pokedex which is Electric Pokemon
//This is our Electric Pokemon Screen
class ElectricScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Electric Pokemon"),
),
body: Center(
child: RaisedButton(
child: Text('Go back!'),
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
Navigator.pop(context);
}, //onPressed
), //RaisedButton
), //Center
); //Scaffold
}
}
Now we have the screen setup, we need to add to our routes
So the MyApp class will look like this now
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
// Start the app with the "/" named route. In this case, the app starts
// on the MainScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the MainScreen widget.
'/': (context) => MainScreen(),
// When navigating to the "/second" route, build the ElectricScreen widget.
'/electric': (context) => ElectricScreen(),
},
);
}
}
Then, finally to know what it will do when you click or tap the menu Electric from the Drawer, let remove below lines of codes
Then replace it with this
// Close the drawer
Navigator.pop(context);
Navigator.pushNamed(context, '/electric');
So that means it will look like below
Now Run the Application
Click the Drawer
Then, click Electric
You will see that it goes to a new screen
Either press the Go back! button or the back arrow button at the top to go back to the main screen
Now we are ready to create our second screen that is for the Fire Pokemon
Let us recopy the ElectricScreen and paste it at the end of the our existing code
Now let us change the values (see text in bold)
//This is our Fire Pokemon Screen
class FireScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Fire Pokemon"),
),
body: Center(
child: RaisedButton(
child: Text('Go back!'),
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
Navigator.pop(context);
}, //onPressed
), //RaisedButton
), //Center
); //Scaffold
}
}
Next, we add the routes
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
// Start the app with the "/" named route. In this case, the app starts
// on the MainScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the MainScreen widget.
'/': (context) => MainScreen(),
// When navigating to the "/second" route, build the ElectricScreen widget.
'/electric': (context) => ElectricScreen(),
'/fire': (context) => FireScreen(),
},
);
}
}
Then finally, add the action when the item is tap from the Drawer item
Code will be
ListTile(
title: Text('Fire'),
onTap: () {
// Close the drawer
Navigator.pop(context);
Navigator.pushNamed(context, '/fire');
},
),
So overall the entire code will be
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
// Start the app with the "/" named route. In this case, the app starts
// on the MainScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the MainScreen widget.
'/': (context) => MainScreen(),
// When navigating to the "/second" route, build the ElectricScreen widget.
'/electric': (context) => ElectricScreen(),
'/fire': (context) => FireScreen(),
},
);
}
}
//Our Main Screen that holds the menus / items
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
//leading: new Icon(Icons.menu),
titleSpacing: 0.0,
title:
Text('Pokemon'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () {
// do something
},
),
],
),
body: Center(
child: Text('This is the fifth lesson in Flutter'),
),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('POKEDEX'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Electric'),
onTap: () {
// Close the drawer
Navigator.pop(context);
Navigator.pushNamed(context, '/electric');
},
),
ListTile(
title: Text('Fire'),
onTap: () {
// Close the drawer
Navigator.pop(context);
Navigator.pushNamed(context, '/fire');
},
),
ListTile(
title: Text('Grass'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Ice'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Water'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
//This is our Electric Pokemon Screen
class ElectricScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Electric Pokemon"),
),
body: Center(
child: RaisedButton(
child: Text('Go back!'),
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
Navigator.pop(context);
},
),
),
);
}
}
//This is our Fire Pokemon Screen
class FireScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Fire Pokemon"),
),
body: Center(
child: RaisedButton(
child: Text('Go back!'),
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
Navigator.pop(context);
},
),
),
);
}
}
Run the application and check when you click the two items
In case you missed the previous lessons and you want to follow along
Renaming Project and Module in Android Studio
There you go guys, hope you enjoy the learning as much as I do
Let me know what you think? :)