flutter_mediator 1.0.0+1 copy "flutter_mediator: ^1.0.0+1" to clipboard
flutter_mediator: ^1.0.0+1 copied to clipboard

outdated

Flutter mediator is a MVC state management package base on InheritedModel with automatic aspect management to make them simpler, easier, and intuitive to use.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_mediator/mediator.dart';

import 'models/list_model.dart';
import 'models/my_model.dart';
import 'widgets/BottomNavigationController.dart';
import 'widgets/widget_extension.dart';

const double Width = 150;

void main() {
  runApp(
    MultiHost.create2(
      MyModel(updateMs: 1000), // model that extends Publisher
      ListModel(updateMs: 500), // model that extends Publisher
      child: MyApp(),
    ),

    /// single host: the original form, or use MultiHost.create1
    // Host(
    //   model: MyModel(updateMs: 1000),
    //   child: MyApp(),
    // ),
  );
}

class MyApp extends StatelessWidget {
  final bottomNavItems = [
    const BottomNavigationBarItem(
      title: Text('Buttons'),
      icon: Icon(Icons.lightbulb_outline),
      activeIcon: Icon(Icons.library_books),
      // backgroundColor: ,
    ),
    const BottomNavigationBarItem(
      title: Text('ListView'),
      icon: Icon(Icons.new_releases),
      activeIcon: Icon(Icons.payment),
      // backgroundColor: ,
    ),
    const BottomNavigationBarItem(
      title: Text('Info'),
      icon: Icon(Icons.info_outline),
      activeIcon: Icon(Icons.inbox),
      // backgroundColor: ,
    ),
  ];
  final pages = [buttonPage(), cardPage(), infoPage()];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Mediator Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: BottomNavigationWidget(
        pages: pages,
        bottomNavItems: bottomNavItems,
        selectedColor: Colors.amber[800],
        backgroundColor: Colors.black54.withOpacity(0.5),
        selectedIndex: 0,
      ),
    );
  }
}

Widget buttonPage() {
  return Row(
    children: [
      Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          AllListener(),
          FooListener(),
          BarListener(),
          BarListener(),
          StarListener(),
          Str1Listener(),
          Int1Listener(),
          ChainReactListener(),
        ],
      ),
      Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          FooUpdater(),
          BarUpdater(),
          BothUpdater(),
          AllUpdater(),
          Str1Updater(),
          Int1Updater(),
          FutureUpdater(),
          NoUpdater(),
          Tick1(),
          Tick2(),
          Tick3(),
        ],
      ),
    ],
  );
}

Widget cardPage() {
  return ListItemView();
}

class ListItemView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// original form
    // return Subscriber<ListModel>(
    //   aspects: ListEnum.ListUpdate,
    //   create: (context, model) {

    /// with helper
    // return ListEnum.ListUpdate.subModel<ListModel>(create: (context, model) {
    return ListEnum.ListUpdate.subListModel(create: (context, model) {
      final data = model.data;
      return GridView.builder(
        itemCount: data.length,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount:
                (MediaQuery.of(context).orientation == Orientation.portrait)
                    ? 5
                    : 10),
        itemBuilder: (context, index) {
          final item = data[index];
          return Card(
            color: item.color,
            child: GridTile(
              footer: Text(item.units.toString()),
              child: Text(item.item),
            ).padding(const EdgeInsets.all(7.0)),
          );
        },
      );

      //* List View
      // return ListView.builder(
      //   itemCount: data.length,
      //   itemBuilder: (context, index) {
      //     final item = data[index];
      //     return ListTile(
      //       title: Text(item.item),
      //       subtitle: Text(item.units.toString()),
      //     ).background(item.color);
      //   },
      // );
    });
  }
}

Widget infoPage() {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      const Text('MyModel:'),
      'tick1'.subMyModel(create: (context, myModel) {
        return Text('tick1 is ${myModel.tick1}');
      }),

      const SizedBox(height: 30),

      // ListEnum.ListUpdate.subListModel(create: (context, model) {
      ListEnum.ListUpdate.subModel<ListModel>(create: (context, listModel) {
        return Column(
          children: [
            const Text('ListModel:'),
            Text('sales:${listModel.data.length}'),
            Text('Total units:${listModel.getTotalUnits()}'),
          ],
        );
      }),
    ],
  ).center();
}

class AllListener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // return Subscriber<MyModel>(
    // return null.subMyModel(
    return null.subModel<MyModel>(
      create: (context, model) {
        final aspects = model.frameAspect;
        final str = aspects.isEmpty ? '' : '$aspects received';
        return Text(
          str,
          softWrap: true,
          textAlign: TextAlign.center,
        );
      },
    ).sizeBox(width: Width, height: 30);
  }
}

class FooListener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Subscriber<MyModel>(
      aspects: 'foo',
      create: (context, model) {
        print('foo build');
        return Text('Foo is ${model.foo}');
      },
    );
  }
}

class BarListener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return 'bar'.subModel<MyModel>(
      create: (context, model) {
        print('bar build');
        return Text('Bar is ${model.bar}');
      },
    );
  }
}

class StarListener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return 'star'.subModel<MyModel>(
      create: (context, model) {
        print('star build');
        return Text('Star is ${model.star}');
      },
    );
  }
}

class Str1Listener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return 'str1'.subMyModel(
      create: (context, model) {
        print('str1 build');
        return Text('Str1 is ${model.str1}');
      },
    );
  }
}

class Int1Listener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// original form:
    // return Subscriber<MyModel>(
    //   aspects: 'int1',
    return 'int1'.subModel<MyModel>(
      create: (context, model) {
        print('int1 build');
        return Text('Int1 is ${model.int1}');
      },
    );
  }
}

int httpResCounter = 0;

class ChainReactListener extends StatelessWidget {
  Future<int> _futureHttpTask() async {
    await Future.delayed(const Duration(milliseconds: 0));
    return ++httpResCounter;
  }

  @override
  Widget build(BuildContext context) {
    return 'chainStr1'.subModel<MyModel>(create: (context, model) {
      return FutureBuilder(
        future: _futureHttpTask(),
        initialData: httpResCounter,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          Widget child;
          if (snapshot.hasData) {
            child = Text('str1 chain counter: $httpResCounter');
          } else {
            child = Text('str1 init counter: $httpResCounter');
          }
          return Center(child: child);
        },
      );
    });
  }
}

class FooUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = context.getModel<MyModel>();
    return RaisedButton(
      child: const Text('Update foo'),
      onPressed: () => model.foo++,
    );
  }
}

class BarUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = getMyModel(context);
    return RaisedButton(
        child: const Text('Update bar'), onPressed: () => model.bar++);
  }
}

class BothUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = getMyModel(context);
    return const Text('Update both').raisedButton(
      onPressed: () => model.increaseBoth(),
    );
  }
}

class AllUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = getMyModel(context);
    return RaisedButton(
      child: const Text('Update all'),
      onPressed: () => model.increaseAll(),
    );
  }
}

class Str1Updater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = getMyModel(context);
    return RaisedButton(
      child: const Text('Update Str1'),
      onPressed: () => model.updateStr1(),
    );
  }
}

class Int1Updater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = context.getModel<MyModel>();
    return RaisedButton(
      child: const Text('Update Int1'),
      onPressed: () => model.updateInt1(),
    );
  }
}

class FutureUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: const Text('Future Int1:1sec'),
      onPressed: () => context.getModel<MyModel>().futureInt1(),
    );
  }
}

class NoUpdater extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = getMyModel(context);
    return RaisedButton(
      child: const Text('Update none'),
      onPressed: () => model.updateNone(),
    );
  }
}

class Tick1 extends StatelessWidget {
  final _ColorRegistry r = _ColorRegistry();

  @override
  Widget build(BuildContext context) {
    return 'tick1'
        .subMyModel(
          create: (context, model) {
            // print('tick1 build');
            return _ColoredBox(
              color: r.nextColor(),
              child: Text('tick1 is ${model.tick1}'),
            );
          },
        )
        .padding(const EdgeInsets.all(5.0))
        .sizeBox(width: Width, height: 60);
  }
}

class Tick2 extends StatelessWidget {
  final _ColorRegistry r = _ColorRegistry();

  @override
  Widget build(BuildContext context) {
    return 'tick2'
        .subMyModel(
          create: (context, model) {
            // print('tick2 build');
            return _ColoredBox(
              color: r.nextColor(),
              child: Text('tick2 is ${model.tick2}'),
            );
          },
        )
        .padding(const EdgeInsets.all(5.0))
        .sizeBox(width: Width, height: 60);
  }
}

class Tick3 extends StatelessWidget {
  final _ColorRegistry r = _ColorRegistry();

  @override
  Widget build(BuildContext context) {
    return 'tick3'
        .subMyModel(
          create: (context, model) {
            // print('tick3 build');
            return _ColoredBox(
              color: r.nextColor(),
              child: Text('tick3 is ${model.tick3}'),
            );
          },
        )
        .padding(const EdgeInsets.all(5.0))
        .sizeBox(width: Width, height: 60);
  }
}

class _ColorRegistry {
  final List<Color> colors = [
    Colors.pink,
    Colors.red,
    Colors.orange,
    Colors.yellow,
    Colors.lightGreen,
    Colors.green,
    Colors.blue,
    Colors.indigo,
    Colors.purple,
  ];

  int _idx = 0;

  Color nextColor() {
    if (_idx >= colors.length) {
      _idx = 0;
    }
    return colors[_idx++];
  }
}

class _ColoredBox extends StatelessWidget {
  const _ColoredBox({Key key, this.color, this.child}) : super(key: key);

  final Color color;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      color: color,
      child: child,
    );
  }
}
6
likes
0
pub points
0%
popularity

Publisher

unverified uploader

Flutter mediator is a MVC state management package base on InheritedModel with automatic aspect management to make them simpler, easier, and intuitive to use.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

flutter

More

Packages that depend on flutter_mediator