flutter mvvm模式

刚入手flutter几天,写个仿微信的项目来加深flutter印象,本项目采用的mvvm模式,本文重点介绍mvvm。因为关于flutter 本身的 安装,构建UI 等等,比比皆是,除非疑难杂症,架构模式这种东西,跟你具体用什么语言、什么框架,关系不大。简单讲就是你怎么组织代码。便于逻辑清晰,更具条理。避免代码一整驼一整驼,甚至复制粘贴,全是重复、冗余代码。
mvc -> mvp -> mvvm, 不断演进与升级。了解一下分别是什么后,mvvm 的一大优势便是 view 与 model 双向绑定,任何一方的变动,都可以通知到另外一方。而另外两个,几乎是 单方主动请求

mvvm 源码

在这里插入图片描述
viewModel 作为 view 和 model 的中间者,处理view发出的请求,并在model数据等变化时,通知view 更新UI。

好了,话不多说,下面开始代码介绍,

1. 添加插件:provider , rxdart。 pubspec.yaml 文件
在这里插入图片描述

2. 首先我们创建一个ViewModel的基类

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:provide/provide.dart';
import 'package:rxdart/rxdart.dart';

/// BaseProvide
class BaseProvide with ChangeNotifier {

  CompositeSubscription compositeSubscription = CompositeSubscription();


  /// add [StreamSubscription] to [compositeSubscription]
  ///
  /// 在 [dispose]的时候能进行取消
  addSubscription(StreamSubscription subscription){
    compositeSubscription.add(subscription);
  }

  @override
  void dispose() {
    super.dispose();
    compositeSubscription.dispose();
  }
}

/// page的基类 [PageProvideNode]
///
/// 隐藏了 [ProviderNode] 的调用
abstract class PageProvideNode extends StatelessWidget {
  /// The values made available to the [child].
  final Providers mProviders = Providers();

  Widget buildContent(BuildContext context);

  @override
  Widget build(BuildContext context) {
    return ProviderNode(
      providers: mProviders,
      child: buildContent(context),
    );
  }
}

abstract class BaseState<T extends StatefulWidget> extends State<T> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }
}

3.编写model,采用Dio


class UserRes {

  static Future<BaseRes> getUserRecord() async {

//    Response response;
//    Dio dio = new Dio();
//    response = await dio.get("http://localhost:8098/adapi/test/getRecord");

    var data =  _data.userRecord;
    return BaseRes.fromJson(data);
  }

  static Future<BaseRes> getUserTel() async {

//    Response response;
//    Dio dio = new Dio();
//    response = await dio.get("http://localhost:8098/adapi/test/getUserTel");

    var data =  _data._userTel;
    return BaseRes.fromJson(data);
  }

}

4.下面我们来写ViewModel 继承 BaseProvide

import 'dart:convert';

import 'package:rxdart/rxdart.dart';
import 'package:weixintest/base/base.dart';
import 'package:weixintest/model/userInfo.dart';

class ChatProvider extends BaseProvide{
  List<dynamic> _chatData=[];

  List<dynamic> get chatData => _chatData;

  set chatData(List<dynamic> value) {
    _chatData = value;
    notifyListeners();
  }

	// 请求数据,对请求回来的数据进行赋值
  Observable getChatData() {
    return Observable.fromFuture(UserRes.getUserRecord())
        .doOnData((data) {
      List<dynamic>  res= [];
      var red = data.data;
      for (var value in red) {
        res.add(json.decode(value));
      }
      chatData = res;
    })
        .doOnError((e, stacktrace) {})
        .doOnListen(() {})
        .doOnDone(() {});
  }
}

5. 开始编写View

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:weixintest/tools/commUtils.dart';
import 'package:weixintest/viewmodel/chat.dart';

class Log extends StatefulWidget {
  @override
  _ListContent createState() => new _ListContent();
}

// 列表
class _ListContent extends State<Log> {
  ChatProvider _provide = ChatProvider();
  final _subscription = CompositeSubscription();

  @override
  void initState() {
    super.initState();
    _getInfo();
  }

  _getInfo() {
  	// 调用getChatData().listen 来监听数据
    var s = _provide.getChatData().listen((res) {});
    _subscription.add(s);
  }

  @override
  Widget build(BuildContext context) {

	//直接引用数据,对数据进行绑定。
    return ChangeNotifierProvider.value(
          value: _provide,
          child: Consumer<ChatProvider>(
            builder: (_, value, child) {
              return Expanded(
                child:Container(
                  color: Colors.white,
                  child:ListView.builder(
                      itemCount: _provide.chatData.length,
                      itemBuilder: (context, index) {
                        return ListTile(
                            leading: Container(
                              width: w(80), // 屏幕适应
                              height: w(80),
                              decoration: BoxDecoration(
                                image: DecorationImage(
                                    image: AssetImage(
                                        _provide.chatData[index]["img"]),
                                    fit: BoxFit.fitWidth),
                                borderRadius:
                                BorderRadius.all(Radius.circular(5.0)),
                              ),
                            ),
                            title: Text(_provide.chatData[index]["title"]),
                            subtitle:
                            Text(_provide.chatData[index]["content"]));
                      })  ,
                ),
              ) ;
            },
          ));
  }

OK 简单的mvvm模式编写完成,附上源码

关注公众号【程序员每日一学】让我们每天一起进步~

在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小张丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值