A lightweight jumpstart for your flutter application. Navigation without context. better logs. easy singletons and more.


License
Other

Documentation

Pub style: effective dart GitHub stars

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.