当前位置: 首页 > 工具软件 > Flutter MVVM > 使用案例 >

Flutter MVVM框架搭建

佘茂才
2023-12-01

去年公司Flutter的项目采用的是类似Android 里面的MVP(Model View Persenter)模式,Model和View以及Persenter之间采用接口解耦,虽然采用插件来生成对应的基本模板,渐渐的发现接口过多,慢慢的就发现很多问题。

主要的问题是逻辑复杂的情况下,接口会比较多,而且Presenter也不太好复用(可能技术太菜了),之后引入Provider框架来解决页面局部刷新功能。

之后就想到MVVM框架,View和ViewModel可以采用Provider来做事件传递,做双向绑定

1.大致框架

View: 主要是就是各类Widget Page页面

ViewModel: 主要是继承ChangeNotifier

Mode:主要是从网络/数据库/本地资源文件等

ViewModel ->Model 之间可以通过Future方式获取数据

ViewModel <-> View之间通过Provider来双向数据绑定,实时响应

由于Provider可以做到细粒度的局部刷新,一些公用的Widget可以做到组合使用,而对应的ViewModel的逻辑也可以很好的与Widget通过ChangeNotifier复用使用。

2.View层

对应的是普通的StatefulWidget界面

由于需要绑定对应的ViewModel,需要在对应的模块中通过Provider引入

下面是普通的Provider的引入方法

Widget _authGestureWidget() {
    return ChangeNotifierProvider<SecuritySettingsNotifier>.value(
        value: _settingsNotifier,
        child: Consumer<SecuritySettingsNotifier>(
          builder: (context, settingsNotifier, _) {
            return Container(
              color: DHColor.colorFFFFFF,
              margin: EdgeInsets.only(bottom: DHSize.dp(8)),
              child: _settingsNotifier.canAuch
                  ? DHListTileLine(
                      leadingText: "每次打开都需要验证身份",
                      isDivider: false,
                      trailing: DHSwitchButton(
                          value: _settingsNotifier.isAuthGesture,
                          activeColor: DHColor.color_B69E74,
                          onChanged: (bool isOpen) {
                            handleTapAuth();
                          }),
                      isTrailing: false,
                    )
                  : Container(),
            );
          },
        ));
  }

对应的只是一个验证身份的模块,具体需要去了解一下Provider的用法

3.ViewModel展示

ViewModel 主要是展示对应的业务逻辑 下面展示一个比较普通的业务逻辑

class SecuritySettingsNotifier with ChangeNotifier {
  ///指纹密码
  bool _isAuthPWD = false;

  bool get isAuthGesture => _isAuthPWD;

  set isAuthGesture(bool value) {
    _isAuthPWD = value;

    notifyListeners();
  }

  List<BiometricType> _availableBiometrics;

  List<BiometricType> get availableBiometrics => _availableBiometrics;

  ///是否支持脸部识别
  bool canFaceAuth = false;

  ///是否支持指纹
  bool canTouchAuth = false;

  ///设备是否支持脸部、指纹识别
  bool canAuch = false;

  set availableBiometrics(List<BiometricType> value) {
    _availableBiometrics = value;

    if (_canAvailableBiometrics()) {
      for (BiometricType type in _availableBiometrics) {
        if (BiometricType.face == type) {
          canFaceAuth = true;
        } else if (BiometricType.fingerprint == type) {
          canTouchAuth = true;
        }
      }
    }

    canAuch = (canFaceAuth || canTouchAuth);

    notifyListeners();
  }

  bool _canAvailableBiometrics() {
    return _availableBiometrics != null && _availableBiometrics.isNotEmpty;
  }
}

主要用于控制设置页面的是否支持指纹识别相关的设置

4.普通的Model

此时的Model展示就和一般的获取数据类似

class MineInfoModel extends AbstractModel {
  @override
  void dispose() {
    HttpManager().cancel(tag);
  }

  Future<MineInfoBean> getMineInfoDetail() {
    return HttpManager().postAsync(
      url: Api.getUserInfo,
      jsonParse: (val) => MineInfoBean.fromJson(val),
      tag: tag,
    );
  }
}

直接获取对应的数据即可

5.总结

ViewModel 获取数据直接通过接口调用Model的对应方法即可,通过Future then等操作

View和ViewModel之间则是通过Provider联动,但是会存在一些提交数据的操作,就需要通过回调CallBack的操作来直接响应对应的数据结果

而对于列表类型的数据或者是获取数据的则可通过Provider的ChangeNotifier 局部刷新Widget来驱动界面的更新

具体后续会添加上对应的Demo展示

 类似资料: