NyPage
- Introduction
- Creating a New Page
- Using Controllers
- How to Use NyPage
- Passing Data to Different Pages
- Helper
Introduction
In this section, we will learn about NyPage
.
Most Flutter projects will likely need to create pages for example, a login page, a dashboard page, a profile page, etc.
Nylo's NyPage
class helps you build the UI quicker with less code, let's take a deep dive.
In the terminal, if you run the below command, it will create a new page for you.
dart run nylo_framework:main make:page dashboard
The new page will be created in resources/pages/
resources/pages/dashboard_page.dart
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
class DashboardPage extends NyPage {
static String path = '/dashboard';
@override
init() async {
// initialize the page
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: Container(
child: Text("Hello World") // Build your UI
),
),
);
}
}
Here are some important things to note:
-
path
is the route path for the page. You can use this path to navigate to the page for examplerouteTo(Dashboard.path)
. -
init
is called when the page is created. You can use this method to load data, set data in the class or do any other initialization work. -
build
contains the Widget that will be displayed on the UI.
Continue reading to learn more about NyPage
Creating a new page
You can create a new page by running the below command in the terminal.
dart run nylo_framework:main make:page settings
The new page will be created in resources/pages/
resources/pages/settings_page.dart
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
class SettingsPage extends NyPage {
static String path = '/settings';
@override
init() async {
// initialize the page
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Settings")
),
body: SafeArea(
child: Container(
child: Text("Hello World") // Build your UI
),
),
);
}
}
Using Controllers
Controllers are a great way to separate your business logic from your UI.
The easiest way to create a page and controller is by running the below command in the terminal.
dart run nylo_framework:main make:page dashboard -c
# or if you have Metro
metro make:page dashboard -c
The new page and controller will be created in resources/pages/ and app/controllers/
This is the code it will generate for you.
Controller - DashboardController
app/controllers/dashboard_controller.dart
import 'controller.dart';
import 'package:flutter/widgets.dart';
class DashboardController extends Controller {
// add variables/methods/functions here
construct(BuildContext context) {
super.construct(context);
}
// Example method
bool isProUser() {
User user = Backpack.instance.auth();
if (user.isPro) {
return true;
}
return false;
}
}
Page - DashboardPage
resources/pages/dashboard_page.dart
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class DashboardPage extends NyPage<DashboardController> {
static String path = '/dashboard';
@override
init() async {
// initialize the page
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: Container(
child: InkWell(
onTap: () {
bool isProUser = controller?.isProUser(); // call a method from the controller
/// do something
},
child: Text("Subscribe") // Build your UI
)
),
),
);
}
}
You can learn more about controllers here
How to use NyPage
In this section, we'll take a look at:
Flutter apps often need to load data from an API, pass data from one page to another or initialize classes.
When using NyPage
we'll show how you can handle some of these scenarios.
Initializing Data
Each page has an init
method that is called when the page is created.
You can use this method to initialize data, classes, etc.
Try not to set data in the NyPage
class, instead use a controller to set data/variables.
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
import 'package:firebase_core/firebase_core.dart';
class DashboardPage extends NyPage<DashboardController> {
static String path = '/dashboard';
@override
init() async {
/* Example with Firebase
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
*/
}
Future<List<String>> _getFavouriteFood() async {
await Future.delayed(Duration(seconds: 2));
return ["Rice", "Pasta", "Burger"];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: NyListView(
child: (BuildContext context, dynamic food) {
return ListTile(
title: Text(food)
);
},
data: _getFavouriteFood
),
),
);
}
}
Loading Data from an API
When loading data from an API, it's recommended to use an API Service.
This is how you can load data using NyPage.
First, create a controller, e.g. DashboardController
.
import 'package:flutter_app/app/networking/api_service.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'controller.dart';
import 'package:flutter/widgets.dart';
class DashboardController extends Controller {
List<dynamic> jsonPlaceHolderData = [];
construct(BuildContext context) {
super.construct(context);
}
loadJsonPlaceHolderData() async {
jsonPlaceHolderData = await api<ApiService>((request) => request.get("https://jsonplaceholder.typicode.com/posts"));
}
}
Then, use the Controller in your NyPage
.
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class DashboardPage extends NyPage<DashboardController> { // uses DashboardController
static String path = '/dashboard';
@override
init() async {
}
@override
boot() async {
await Future.delayed(Duration(seconds: 2));
await controller?.loadJsonPlaceHolderData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: NyListView(
child: (BuildContext context, dynamic data) {
return ListTile(
title: Text(data['title'])
);
},
data: () async {
return controller?.jsonPlaceHolderData; // returns the data from the controller
}
),
),
);
}
@override
Widget loading(BuildContext context) {
return Scaffold(
body: loadingWidget, // This Widget will be used when the page is loading
);
}
}
You'll notice in the above example that we are using the boot
method to load the data.
The boot method allows you to load data. While the page is loading, it will display the loading
widget as seen in the example above.
You can override it to customize the look for the loading state.
Learn more about networking here.
Passing Data to Different Pages
You can pass data to different pages by using the routeTo
method.
Let's imagine we have two pages, DashboardPage and ProfilePage.
From the DashboardPage we want to pass data to the ProfilePage.
This is how we can do it.
/// Dashboard Page
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class DashboardPage extends NyPage<DashboardController> {
static String path = '/dashboard';
@override
init() async {
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: Column(
children: [
InkWell(
child: Text("Route To Profile"),
onTap: () {
routeTo(ProfilePage.path, data: {"name": "Anthony"});
},
)
],
)
),
);
}
}
And here's the ProfilePage.
/// Profile Page
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class ProfilePage extends NyPage {
static String path = '/profile';
@override
init() async {
dynamic data = controller?.data();
NyLogger.debug(data); // {"name": "Anthony"}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Profile")
),
);
}
}
Helpers
The NyPage
class has some great helpers you can use.
The helpers are:
You can call these helpers in your NyPage
, let's take a look at some examples.
Refresh Page
You can refresh the page by calling the refreshPage
method.
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class DashboardPage extends NyPage<DashboardController> {
static String path = '/dashboard';
@override
boot() async {
await Future.delayed(Duration(seconds: 2));
await controller?.loadProfileData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
actions: [
IconButton(onPressed: () {
refreshPage(); // refreshes the page. The `boot` method will be called again
}, icon: Icon(Icons.refresh))
],
),
body: SafeArea(
child: Column(
children: [
// Widgets...
],
)
),
);
}
}
Updating the state
You can update the state by using the setState
parameter on the refreshPage
method too.
refreshPage(setState: () {
// update the state here
});
Here's an example in a widget.
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
class DashboardPage extends NyPage<DashboardController> {
static String path = '/dashboard';
@override
init() async {
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
actions: [
IconButton(onPressed: () {
refreshPage(setState: () {
controller?.name = "Josh"; // update variables in the state
});
}, icon: Icon(Icons.refresh))
],
),
);
}
}
Showing Toast Notifications
You can show toast notifications by calling one of the following:
-
showToastSuccess(description: "Welcome back")
-
showToastDanger(description: "Your card has expired")
-
showToastWarning(description: "That email is already taken")
-
showToastInfo(description: "5 new messages")
If you want to customize the look of notifications, check out the resources/widgets/toast_notification_widget.dart file.
Change Language
You can change the language by calling the changeLanguage
method.
changeLanguage("es"); // switch to Spanish locale
Read the docs on localization here to understand more.
Validation
You can validate a form by calling the validate
method.
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
class DashboardPage extends NyPage {
static String path = '/dashboard';
@override
init() async {
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard")
),
body: SafeArea(
child: InkWell(
child: Text("Login"),
onTap: _login,
)
),
);
}
_login() {
String email = "anthony@mail.com";
String password = "password1";
validate(rules: {
"email": "email",
"password": r'regex:([0-9]+)' // password contains one number
}, data: {
"email": email,
"password": password
}, onSuccess: () {
NyLogger.debug("Success!");
});
}
}
Read the docs on validation here to understand more.