flutter中的状态管理Provider 实现MVVM

218 阅读2分钟

官方早期也提供的一种状态管理模式叫做BLOC。这种方式依赖于第三方包rxDart,以流(Stream)的方式很好地解决了setState()的问题。但是这种学习难度较大,对Flutter的新手并不友好。后来出现了一种第三方库Provider,这是一种先进的状态管理和依赖注入的工具,并且易于学习和理解,所以目前官方也推荐首选Provider

本文我们也是主要介绍如何使用Provider来实现MVVM模式。

其中定义的baseModel   实现 ChangeNotifier 实时对数据进行更新后通知 ,里面存放数据请求时,界面如何展示,请求结束后 界面如何提示等 类似于 dialog的展示和销毁,还有实现notifyListeners 判断界面是否销毁,数据是否刷新

其中的定义的BaseView


import 'package:flutter/material.dart';

import 'package:flutter_provider_mvvm/viewmodels/base_model.dart';

import 'package:provider/provider.dart';



//baseview 就是一个组件weight

class BaseView<T extends BaseModel> extends StatefulWidget {

  final Widget Function(BuildContext context, T model, Widget child) builder;



  final T model;

  final Widget child;

  final Function(T) onModelReady;



  BaseView({Key key, this.model, this.builder, this.child, this.onModelReady}) : super(key: key);



  @override

  _BaseViewState<T> createState() => _BaseViewState<T>();

}



class _BaseViewState<T extends BaseModel> extends State<BaseView<T>> {

  T model;



  @override

  void initState() {

    //方便初始化 一些操作,类似于刚进页面需要网络请求等

    // 为什么这里我们需要使用StatefulWidget呢?因为我们需要在initState()在所有的子类中给出初始化的机会。

    // 在所有需要应用MVVM模式的Widget都可以继承这个基类,传入ChangeNotifierProvider所需要的参数,其中包括viewModel,builder,child,还有初始化时的回调方法onModelReady()。

    model = widget.model;

    if (widget.onModelReady != null) {

      widget.onModelReady(model);

    }

    super.initState();

  }



//ChangeNotifierProvider<T extends ChangeNotifier> 实时通知

  //通过Consumer 内部结构 进行接收

  /**

   * class Consumer<T> extends SingleChildStatelessWidget {

      /// {@template provider.consumer.constructor}

      /// Consumes a [Provider<T>]

      /// {@endtemplate}

      Consumer({

      Key key,

      @required this.builder,

      Widget child,

      })  : assert(builder != null),

      super(key: key, child: child);



      /// {@template provider.consumer.builder}

      /// Build a widget tree based on the value from a [Provider<T>].

      ///

      /// Must not be `null`.

      /// {@endtemplate}

      final Widget Function(BuildContext context, T value, Widget child) builder;



      @override

      Widget buildWithChild(BuildContext context, Widget child) {

      return builder(

      context,

      Provider.of<T>(context),

      child,

      );

      }

      }

   */

  @override

  Widget build(BuildContext context) {

    return ChangeNotifierProvider<T>(

      child: Consumer<T>(

        builder: widget.builder,

        child: widget.child,

      ),

      create: (BuildContext context) {

        return model;

      },

    );

  }

}