功能 GitHub地址
Provider provider rrousselGit/provider
scope_model scoped_model brianegan/scoped_model
Redux flutter_redux brianegan/flutter_redux
BLoc flutter_bloc felangel/bloc
RxDart rxdart ReactiveX/rxdart
Mobx flutter_mobx mobxjs/mobx.dart


scope_model

model.dart

  1. import 'package:scoped_model/scoped_model.dart';
  2. class CountModel extends Model{
  3. int _count = 0;
  4. get count => _count;
  5. void increment(){
  6. _count++;
  7. notifyListeners();
  8. }
  9. CountModel of(context) =>
  10. ScopedModel.of<CountModel>(context);
  11. }

main.dart

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

import 'model/index.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  //创建顶层状态
  CountModel countModel = CountModel();

  @override
  Widget build(BuildContext context) {
    return ScopedModel<CountModel>(
      model: countModel,
      child: new MaterialApp(
        title: 'ScopedModel Demo',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: FirstScreen(),
      ),
    );
  }
}

// ----------------------------------------------------------
class FirstScreen extends StatefulWidget {
  @override
  FirstScreenState createState() => FirstScreenState();
}

class FirstScreenState extends State<FirstScreen> {

  //静态获取model用法实例
  Model getModel(BuildContext context){
    //直接使用of
    final countModel = ScopedModel.of<CountModel>(context, rebuildOnChange: true);
    //使用CountModel中重写的of
    final countModel2 = CountModel().of(context);

    countModel.increment();
    countModel2.increment();
    return countModel;
    //    return countMode2;
  }

  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<CountModel>(
      builder: (context,child,model){
        return Scaffold(
          appBar: AppBar(
            title: Text('Top Screen'),
          ),
          body: Center(
            child: Text(
              model.count.toString(),
              style: TextStyle(fontSize: 48.0),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context){
                return SecondScreen(title: "Under Screen",);
              }));
            },
            child: Icon(Icons.forward),
          ),
        );
      },
    );
  }
}

// ----------------------------------------------------------

class SecondScreen extends StatefulWidget {
  SecondScreen({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  SecondScreenState createState() => new SecondScreenState();
}

class SecondScreenState extends State<SecondScreen> {
  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<CountModel>(builder: (context, child, model) {
      return Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Text(
                'You have pushed the button this many times:',
                style: TextStyle(fontSize: 20.0),
              ),
              Text(
                "${model.count}",
                style: TextStyle(fontSize: 36.0),
              ),
            ],
          ),
        ),
        floatingActionButton: new FloatingActionButton(
          onPressed: () => model.increment(),
          tooltip: 'Increment',
          child: new Icon(Icons.add),
        ), // This trailing comma makes auto-formatting nicer for build methods.
      );
    },
//    rebuildOnChange: false,
    );
  }
}

scoped_demo.zip

flutter_redux

简单代码

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

enum Actions { Increment }

int counterReducer(int state, dynamic action) {
  if (action == Actions.Increment) {
    return state + 1;
  }
  return state;
}



void main() {
  final store = Store<int>(counterReducer, initialState: 0);
  runApp(FlutterReduxApp(
    title: 'Flutter Redux Demo',
    store: store,
  ));
}

class FlutterReduxApp extends StatelessWidget {
  final Store<int> store;
  final String title;
  FlutterReduxApp({Key? key, required this.store, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StoreProvider<int>(
      store: store,
      child: MaterialApp(
        theme: ThemeData.dark(),
        title: title,
        home: Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                StoreConnector<int, String>(
                  converter: (store) => store.state.toString(),
                  builder: (context, count) {
                    return Text(
                      'The button has been pushed this many times: $count',
                      style: Theme.of(context).textTheme.bodyText1,
                    );
                  },
                )
              ],
            ),
          ),
          floatingActionButton: StoreConnector<int, VoidCallback>(
            converter: (store) {
              return () => store.dispatch(Actions.Increment);
            },
            builder: (context, callback) {
              return FloatingActionButton(
                // Attach the `callback` to the `onPressed` attribute
                onPressed: callback,
                tooltip: 'Increment',
                child: Icon(Icons.add),
              );
            },
          ),
        ),
      ),
    );
  }
}

示例

  • Simple example - a port of the standard “Counter Button” example from Flutter
  • Github Search - an example of how to search as a user types, demonstrating both the Middleware and Epic approaches.
  • Todo app - a more complete example, with persistence, routing, and nested state.
  • Timy Messenger - large open source app that uses flutter_redux together with Firebase Firestore.

Companion Libraries