BFastUI - Introduction
State and UI architecture library for flutter inspired by flutter_modular for architecture and ChangeNotifier pattern for states.
Installation
Open your project's pubspec.yaml
and add bfastui
as a dependency:
dependencies:
bfastui: any
You can also provide the git repository as source instead, to try out the newest features and fixes:
dependencies:
bfastui:
git:
url: https://github.com/fahamutech/bfast-ui-flutter.git
Module
You organised your domain in your application in modules. Module is a top level abstraction of your application.
MainModule
This is the bootstrap module for your application. Is only defined once in your application. You
will required to implement initRoutes
and initStates
method
-
initRoutes - You will add all routes of the pages your module will use
-
initStates - You will add all states you will use in your module
class MyApp extends MainModuleAdapter {
@override
List<RouterAdapter> initRoutes(String moduleName) => [];
@override
List<StateAdapter> initStates(String moduleName) => [];
}
ChildModule
This is the feature module to enclose your specific business logic. Your will required to implement the following methods.
-
initRoutes - You will add all routes of the pages your module will use
-
initStates - You will add all states you will use in your module
-
moduleName - This will return your module name, name can be any
String
of your choice
class ProfileModule extends ChildModuleAdapter {
@override
List<RouterAdapter> initRoutes(String moduleName) => [];
@override
List<StateAdapter> initStates(String moduleName) => [];
@override
String moduleName() => 'profile-module';
}
Page
Page is what your see presented by your mobile phone. i.e login page. Page belongs to a specific
module and characterised with url
to navigate to. Page can have one or more components which make
the whole page functional. To create a page you extend PageAdapter
and you will required to
implement build
method which return a Widget
represent that page.
-
build(var args) - your must provide implementation for this method.
args
has the following propertiesfinal Map<String, dynamic> params; final Map<String, dynamic> queryParams; final dynamic data;
class MyPage extends PageAdapter {
@override
Widget build(var args) {
// TODO: implement build
throw UnimplementedError();
}
}
State
State call information of the current view of your page ( s ). State is a ChangeNotifier
class to
be used with provider state management under the hood.
class MyState extends StateAdapter {
}
to notify listerner for changes your will just call notifyListeners()
as you would in ChangeNotifier
class. You can use a state with active widget
either consumer or selector.
We provider factor method to produce either consumer widget or selector component.
class MyHomePage extends PageAdapter {
@override
Widget build(args) {
return Scaffold(
body: Container(
color: Colors.red,
child: Column(
children: [
consumerComponent<MyState>(
builder: (context, state) => Text('${state.count}'),
),
selectorComponent<MyState, int>(
selector: (state) => state.count,
builder: (c, data) => Text('$data'),
)
],
),
),
);
}
}
Route
A Route carry information of where to navigate to in your application and whether to allow someone access or not. You can navigate to another Page or Module.
Route Guard
To create a route guard
class MyRouteAuthGuard extends RouterGuardAdapter {
@override
Future<bool> canActivate(String url) {
// TODO: implement canActivate
throw UnimplementedError();
}
}
when canActivate
resolve to true
the page or a module someone navigate to will be activated
otherwise will return to previous route if available
Complete Application Example
import 'package:bfastui/adapters/main_module.dart';
import 'package:bfastui/adapters/page.dart';
import 'package:bfastui/adapters/router.dart';
import 'package:bfastui/adapters/state.dart';
import 'package:bfastui/controllers/component.dart';
import 'package:bfastui/controllers/module.dart';
import 'package:flutter/material.dart';
class MyHomePage extends PageAdapter {
@override
Widget build(args) {
return Scaffold(
body: Container(
color: Colors.red,
child: Column(
children: [
consumerComponent<MyState>(
builder: (c, state) => Text('${state?.count}'),
),
selectorComponent<MyState, int>(
selector: (s) => s?.count ?? 0,
builder: (c, data) => Text('$data'),
)
],
),
),
);
}
}
class MyState extends StateAdapter {
int count = 0;
increase() {
count += 1;
notifyListeners();
}
decrement() {
count -= 1;
notifyListeners();
}
@override
void onDispose() {}
}
class MyAppModule extends MainModuleAdapter {
@override
List<RouterAdapter> initRoutes(String moduleName) => [
RouterAdapter('/home', page: (c, _) => MyHomePage()),
];
@override
List<StateAdapter> initStates(String moduleName) => [
MyState(),
];
}
void main() {
runApp(
bfastUiApp(
module: MyAppModule(),
component: MaterialApp(
initialRoute: '/home',
),
),
);
}