cubes 0.3.4 copy "cubes: ^0.3.4" to clipboard
cubes: ^0.3.4 copied to clipboard

outdated

Simple State Manager (Focusing on rebuilding only the necessary)

pub package

Cubes

Cubes #

Simple State Manager with dependency injection and no code generation required.

With Cubes, rebuilding only takes place where it is needed!

MVVM based architecture.

Install #

To use this plugin, add cubes as a dependency in your pubspec.yaml file.

Usage #

  • Creating Cube:

class CounterCube extends Cube {
  final count = ObservableValue<int>(value: 0);

  // To List use `ObservableList`.
  // To others objects not primitive remember call `prop.notify();` after modification to notify listeners.

    @override
    void ready() {
      // do anything when view is ready
      super.ready();
    }

    void increment() {
      count.value++;
      if (count.value == 5) {
        onAction({'key': 'param'}); // Method to send anything to view
      }
      if (count.value == 10) {
        onSuccess('Value iguals 10'); // Method to send the success message
      }
      if (count.value == 50) {
        onError('You are clicking too much o.O'); // Method to send the failure message
      }

      // example apply debounce
       runDebounce(
        'increment', // identify
        ()  => print(count.value),
        duration: Duration(seconds: 1),
      );
    }
}

  • Registering Cubes and or dependencies:

import 'package:cubes/cubes.dart';
import 'package:flutter/material.dart';

void main() {
  // register cube
  registerCube((i) => CounterCube());

  // Example register singleton Cube
  // registerCube((i) => CounterCube(),isSingleton: true);

  // Example register repositories or anything
  // registerSingletonDependency((i) => SingletonRepository(i.get());
  // registerDependency((i) => FactoryRepository(i.get());

  runApp(MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    ));
}

  • Creating view with CubeBuilder:

class Home extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return CubeBuilder<CounterCube>(
      onSuccess: (cube, text) {
        print('onSuccess: $text');
      },
      onError: (cube, text) {
        print('onError: $text');
      },
      onAction: (cube, data) {
        print('onAction: $data');
      },
      builder: (context, cube) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Home'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                cube.count.build<int>((value) {
                  return Text(value.toString());
                }),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: cube.increment,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      },
    );
  }
}

or use CubeWidget


class Home extends CubeWidget<CounterCube> {

  @override
  Widget buildView(BuildContext context, CounterCube cube) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            cube.count.build<int>((value) {
              return Text(value.toString());
            }),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: cube.increment,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  void onError(BuildContext context, PokemonCube cube, String text) {
    // TODO: implement onError
    super.onError(context, cube, text);
  }

  @override
  void onSuccess(BuildContext context, PokemonCube cube, String text) {
    // TODO: implement onSuccess
    super.onSuccess(context, cube, text);
  }

  @override
  void onAction(BuildContext context, PokemonCube cube, data) {
    // TODO: implement onAction
    super.onAction(context, cube, data);
  }
}

Cube and its dependencies are injected into CubeBuilder and CubeWidget without the need for any extra configuration.

By doing this:

  cube.count.build<int>((value) {
    return Text(value.toString());
  }),

we register by listening to the Observer count, and every time this variable is changed, the View is notified by running the code block again:

  return Text(value.toString());

This guarantees that in the whole widget tree of your screen, only the necessary is rebuilt.

Testing #


import 'package:flutter_test/flutter_test.dart';

void main() {
  CounterCube cube;
  setUp(() {
    cube = CounterCube();
  });

  tearDown(() {
    cube?.dispose();
  });
  test('initial value', () {
    expect(cube.count.value, 0);
  });

  test('increment value', () {
    cube.increment();
    expect(cube.count.value, 1);
  });

  test('increment value 3 times', () {
    cube.increment();
    cube.increment();
    cube.increment();
    expect(cube.count.value, 3);
  });
}

Example with asynchronous call here

Useful extensions #


    // BuildContextExtensions

    context.goTo(Widget());
    context.goToReplacement(Widget());
    context.goToAndRemoveUntil(Widget(),RoutePredicate);

    context.mediaQuery; // MediaQuery.of(context);
    context.padding; // MediaQuery.of(context).padding;
    context.viewInsets; // MediaQuery.of(context).viewInsets;

    context.sizeScreen; // MediaQuery.of(context).size;
    context.widthScreen; // MediaQuery.of(context).size.width;
    context.heightScreen; // MediaQuery.of(context).size.height;

    context.theme;
    context.scaffold;

Useful Widgets #

AnimatedListCube #

This is a version of AnimatedList that simplifies its use for the Cube context.


  AnimatedListCube<String>(
    itemList: cube.todoList,
    itemBuilder: (context, item, animation, type) {
      return ScaleTransition(
        scale: animation,
        child: _buildItem(item),
      );
    },
  )

Full usage example here.

Internationalization support #

With Cubes you can configure internationalization in your application. in a simple way using .json files.

Using #

Create a folder named lang and put your files with name location. This way:

Add path in your pubspec.yaml:


  # To add assets to your application, add an assets section, like this:
  assets:
   - lang/

In your MaterialApp you can configure the CubesLocalizationDelegate:


    final cubeLocation = CubesLocalizationDelegate(
      [
        Locale('en', 'US'),
        Locale('pt', 'BR'),
      ],
    );

    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'My app',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        localizationsDelegates: cubeLocation.delegates, // see here
        supportedLocales: cubeLocation.supportedLocations, // see here
        home: Home(),
      );
    }

Ready!!! Your application already supports internationalization. Bas get the strings as follows:


  String text = getString('welcome');

Any questions see our example.

40
likes
0
pub points
61%
popularity

Publisher

unverified uploader

Simple State Manager (Focusing on rebuilding only the necessary)

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_localizations, get_it

More

Packages that depend on cubes