刚入手flutter几天,写个仿微信的项目来加深flutter印象,本项目采用的mvvm模式,本文重点介绍mvvm。因为关于flutter 本身的 安装,构建UI 等等,比比皆是,除非疑难杂症,架构模式这种东西,跟你具体用什么语言、什么框架,关系不大。简单讲就是你怎么组织代码。便于逻辑清晰,更具条理。避免代码一整驼一整驼,甚至复制粘贴,全是重复、冗余代码。
mvc -> mvp -> mvvm, 不断演进与升级。了解一下分别是什么后,mvvm 的一大优势便是 view 与 model 双向绑定,任何一方的变动,都可以通知到另外一方。而另外两个,几乎是 单方主动请求
viewModel 作为 view 和 model 的中间者,处理view发出的请求,并在model数据等变化时,通知view 更新UI。
1. 添加插件:provider , rxdart。 pubspec.yaml 文件
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(() {});
}
}
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模式编写完成,附上源码