Why
The floative package takes the name of my youtube channel (and not the other way around).
I started this project to help me create flutter apps more fast (way faster) then if I had to create it from the ground.
It has features such as:
What is being developed as we speak?
- Internationalization
- lazy singletons in Factory
- State management (IN PROGRESS)
- transitions
- routes
- tests
- docs
How to use it?
Starting
Instead of using your normal MaterialApp, use the FloativeMaterialApp
FloativeMaterialApp(
home: HomePage(),
flavor: Flavor.development
)
this will allow us to set everything up for you.
🤔
Navigation - Or even better Ship Things start to get cool here. This module of the application was born because of my need to handle screen navigation inside my view controller. I really didn't wan't to give the controller the context as a dependency imagine the tests. So I decided to implement a way that I wouldn't need the context anymore. Ship was born.
Navigating
Go to another page
Ship.I.to(page: MyPage());
That's it? Yep.
Get back to the previous page
Ship.I.back();
or with some result:
Ship.I.back(result: "my result");
Navigate to another page and replace the current one
Ship.I.replace(page: MyNextPage());
Navigate back to a page (as far as you wan't)
Ship.I.goBackTo(page: MyPage());
Start a page to get a result from it
var result = await Ship.I.startPageForResult<String>(page: MyContentPage());
Want to show a dialog? Fear no more:
Ship.I.showDialog(dialog: MyDialog());
close the dialog
Ship.I.back(result: "My result");
Show the living pages:
Ship.I.debugShowPages();
Factory - Singletons
To make tests easier and have a single management instance for singletons, I created the factory module.
It's really simple to use, just add a singleton the factory:
Floative.I.factory.register<MyInstanceType>(()=>MyInstance());
or register as a lazy singleton
Floative.I.factory.register<MyInstanceType>(()=>MyInstance(), isLazy: true);
Register a factory (this type will return the instance as always new).
Floative.I.factory.registerFactory<MyInstanceType>(()=>MyInstance());
and get them with:
var myInstance = Floative.I.factory.get<MyInstanceType>();
get with args*:
var myInstance = Floative.I.factory.get<MyInstanceType>(args: {
'my_key': 1
});
print(myInstance.args['my_key'].toString());
*In order to do this, you have to implement this in your class:
class MyClass implements FactoryArgs {
@override
Map<String, dynamic> args = <String, dynamic> {};
}
and then you can use:
var myService = Floative.I.factory.get<MyService>(args: {
'api_client': APIClient()
});
class MyService implements FactoryArgs {
final _apiClientKey = 'api_client';
@override
Map<String, dynamic> args = <String, dynamic> {};
Future<Response> getFoo() async {
final client = args[_apiClientKey];
return await client.get('api-my_foo_url.com/foo');
}
}
Internationalization
First, you need to create your Localizations delegate and place it inside our FloativeMaterialApp.
Make sure it extends FloativeIntl class like this:
class MyLocalizationDelegate extends FloativeIntl {
@override
String translate(String key) {
}
@override
FloativeIntl of(BuildContext context) {
}
}
After this, you will be able to access the translate function in your view with the FloativeViewMixin. Or use the TextIntl widget.
Container(
child: TextIntl('my_title_key')
)
And it will translate the the my_title_key from your translations file. Nice, huh?
Mixins
We're still working on them, but I think this one is pretty useful for me.
FloativeViewMixin
Just use it as a regular mixin, but with a bonus:
class MyWidget extends StatelessWidget
with FloativeViewMixin<MyController> {
}
If and only if you has registered your controller in Floative.I.factory then you can access the controller instance with this mixin. And make sure your controller extends FloativeController.
Just use:
class MyWidget extends StatelessWidget
with FloativeViewMixin<MyController> {
void _onCall() {
controller.onCall();
}
}
Reactive - State Management (STILL IN ALPHA)
In order to achieve a better performance than setState((){}), I created the Reactive module. It was built from the ground using concepts like Widget isolation and focusing on performance. I can't benchmark right now, but once it's finished I will definitely do it.
If you still wan't to use, have in mind that you may face some issues.
I haven't, but I can't promise anything.
In your widget or controller place a ReactiveElement (or ReactiveList or ReactiveMap)
ReactiveElement<String> myStringElement = ReactiveElement<String>();
in your widget place the Reactive widget:
Reactive(
element: myStringElement,
builder: (_) {
return Text(myStringElement.value)
}
)
once you change the value of myStringElement the Reactive element will
be rebuilt.
Widgets
You can also use FloativeState
or FloativeStatelessWidget to achieve
the same result as the FloativeViewMixin.
Have in mind that must extend the FloativeController
That's it for now fellows. I hope you enjoy it.
Pull requests are welcome with tests.