Flutter MVVM架构插件fast_mvvm的使用
Flutter MVVM架构插件fast_mvvm的使用
快速开始
fast_mvvm
是一个基于 MVVM 架构的 Flutter 插件,提供了便捷的开发方式来构建复杂的应用。它可以帮助开发者快速实现数据绑定、状态管理、页面刷新等功能。
Demo 讲解
本示例模拟了一个文章列表页面,展示如何使用 fast_mvvm
来实现 MVVM 架构。
UserModel
首先定义一个 UserModel
,用于处理登录和获取文章列表的操作。
class UserModel extends BaseModel {
/// 登录
Future<bool> login(String account, String psd) async {
await Future.delayed(const Duration(seconds: 3));
return true;
}
/// 获取文章列表
Future<DataResponse<ArticleEntity>> getArticleList() async {
await Future.delayed(const Duration(seconds: 1));
var entity = ArticleEntity([
ArticleItem("1", "好的", "内容内容内容内容内容", DateTime.now().toString()),
ArticleItem("1", "好的", "内容内容内容内容内容", DateTime.now().toString()),
]);
DataResponse<ArticleEntity> dataResponse =
DataResponse<ArticleEntity>(entity: entity, totalPageNum: 3);
return dataResponse;
}
}
初始化
在应用启动时,初始化 fast_mvvm
并配置相关参数。
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
@override
void initState() {
initMVVM<BaseViewModel>(
[UserModel()], // 注册模型
controllerBuild: () => EasyRefreshController(), // 初始化控制器
resetRefreshState: (c) => (c as EasyRefreshController).resetRefreshState(),
finishRefresh: (c, {success, noMore}) =>
(c as EasyRefreshController).finishRefresh(success: success, noMore: noMore),
resetLoadState: (c) => (c as EasyRefreshController).resetLoadState(),
finishLoad: (c, {success, noMore}) =>
(c as EasyRefreshController).finishLoad(success: success, noMore: noMore),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: SelectPage(),
);
}
}
SelectPage
SelectPage
是一个选择页面,用户可以选择是否启用数据加载和状态页配置。
class SelectVM extends BaseViewModel {
ValueNotifier<bool> isLoadData = ValueNotifier(true); // 是否加载数据
ValueNotifier<bool> isConfigState = ValueNotifier(false); // 是否单独配置状态页
}
class SelectPage extends StatelessWidget with BaseView<SelectVM> {
@override
ViewConfig<SelectVM> initConfig() => ViewConfig.noLoad(SelectVM());
@override
Widget vBuild(context, SelectVM vm, Widget? child, Widget? state) {
return Scaffold(
appBar: AppBar(title: const Text("选择")),
body: ListView(
children: [
ListTile(
title: const Text("是否加载数据,用来测试状态页和重新加载数据"),
trailing: ValueListenableBuilder<bool>(
valueListenable: vm.isLoadData,
builder: (_, value, __) => Switch(
value: value,
onChanged: (value) => vm.isLoadData.value = value,
),
),
),
ListTile(
title: const Text("是否单独配置状态页,用来测试状态页和重新加载数据"),
trailing: ValueListenableBuilder<bool>(
valueListenable: vm.isConfigState,
builder: (_, value, __) => Switch(
value: value,
onChanged: (value) => vm.isConfigState.value = value,
),
),
),
ListTile(
title: const Text("根布局刷新"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ArticlePage(
true,
configState: vm.isConfigState.value,
loadData: vm.isLoadData.value,
),
),
);
},
),
ListTile(
title: const Text("根布局不刷新"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ArticlePage(
false,
configState: vm.isConfigState.value,
loadData: vm.isLoadData.value,
),
),
);
},
),
],
),
);
}
}
ArticleEntity
定义文章实体类,模拟接口返回的数据结构。
class ArticleEntity extends BaseEntity {
List<ArticleItem> list;
ArticleEntity(this.list);
}
class ArticleItem {
String id;
String title;
String content;
String time;
ArticleItem(this.id, this.title, this.content, this.time);
}
ArticleVM
ArticleVM
是具体的 ViewModel,用于处理文章列表的逻辑。
class ArticleVM
extends BaseListViewModel<UserModel, ArticleEntity, ArticleItem> {
ArticleVM(this.isLoadData);
bool isLoadData = true;
bool firstLoad = true;
ValueNotifier<String> vnTime = ValueNotifier("暂无");
@override
void jointList(ArticleEntity newEntity) => entity.list.addAll(newEntity.list);
@override
List<ArticleItem> get list => entity.list;
@override
Future<DataResponse<ArticleEntity>> requestHttp({
bool isLoad = false,
int page = 1,
Map<String, dynamic>? params,
}) {
if (!isLoadData && firstLoad) {
firstLoad = false;
return null;
}
return model.getArticleList();
}
@override
void initResultData() {
vnTime.value = list[0].time;
}
void modifyFistTime() {
list[0].time = DateTime.now().toString();
vnTime.value = list[0].time;
notifyListeners();
}
}
ArticlePage
ArticlePage
是具体的文章页面,显示文章列表和相关信息。
class ArticlePage extends StatelessWidget with BaseView<ArticleVM> {
const ArticlePage(
this.rootRefresh, {
Key? key,
this.configState = false,
this.loadData = true,
}) : super(key: key);
final bool rootRefresh;
final bool configState;
final bool loadData;
@override
ViewConfig<ArticleVM> initConfig() {
var _empty = configState
? (vm) => Center(child: Text("单独配置:empty"))
: null;
return rootRefresh
? ViewConfig<ArticleVM>(vm: ArticleVM(loadData), empty: _empty)
: ViewConfig.noRoot(vm: ArticleVM(loadData), empty: _empty);
}
@override
Widget vBuild(
BuildContext context, ArticleVM vm, Widget? child, Widget? state) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: const Text("文章")),
bottomNavigationBar: state != null
? SizedBox()
: Container(
color: Colors.amber,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MaterialButton(
onPressed: vm.modifyFistTime,
color: Colors.white,
child: const Text("修改第一个Item时间,测试全局刷新"),
),
ValueListenableBuilder<String>(
valueListenable: vm.vnTime,
builder: (_, value, __) {
return Text("第一个Item时间:$value");
},
),
Text("根布局刷新时间:${DateTime.now().toString()}"),
],
),
),
body: state ??
EasyRefresh(
controller: vm.refreshController,
onLoad: vm.loadMore,
onRefresh: vm.pullRefresh,
child: ListView.builder(
itemCount: vm.list.length,
itemBuilder: (ctx, index) {
return Selector<ArticleVM, ArticleItem>(
selector: (_, aVM) => aVM.list[index],
shouldRebuild: (pre, next) => pre == next,
builder: (_, ArticleItem value, __) => _item(value),
);
},
),
),
);
}
Widget _item(ArticleItem item) {
return Container(
color: Colors.lightGreen,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(4),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(item.title),
Text(item.time),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item.content),
),
],
),
);
}
}
数据刷新
通过 ValueListenableBuilder
和 Selector
实现局部刷新。
ValueListenableBuilder<String>(
valueListenable: vm.vnTime,
builder: (_, value, __) {
return Text("第一个Item时间:$value");
},
)
Selector<ArticleVM, ArticleItem>(
selector: (_, aVM) => aVM.list[index],
shouldRebuild: (pre, next) => pre == next,
builder: (_, ArticleItem value, __) => _item(value),
)
更多关于Flutter MVVM架构插件fast_mvvm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter MVVM架构插件fast_mvvm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
fast_mvvm
是一个用于 Flutter 应用的 MVVM 架构插件,旨在帮助开发者更轻松地实现 Model-View-ViewModel 架构。它提供了一些工具和类,使得开发者可以更高效地管理状态和业务逻辑。
安装 fast_mvvm
首先,你需要在 pubspec.yaml
文件中添加 fast_mvvm
依赖:
dependencies:
flutter:
sdk: flutter
fast_mvvm: ^latest_version
然后运行 flutter pub get
来安装依赖。
使用 fast_mvvm
1. 创建 ViewModel
ViewModel
是 fast_mvvm
的核心部分,它负责处理业务逻辑和状态管理。你需要继承 BaseViewModel
类来创建你的 ViewModel
。
import 'package:fast_mvvm/fast_mvvm.dart';
class MyViewModel extends BaseViewModel {
String _title = "Hello, MVVM!";
String get title => _title;
void updateTitle(String newTitle) {
_title = newTitle;
notifyListeners(); // 通知视图更新
}
}
2. 创建 View
View
是用户界面的部分,它通过 ViewModel
来获取数据和监听状态变化。你可以使用 ViewModelProvider
来将 ViewModel
注入到 View
中。
import 'package:flutter/material.dart';
import 'package:fast_mvvm/fast_mvvm.dart';
import 'my_view_model.dart';
class MyView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelProvider<MyViewModel>(
create: () => MyViewModel(),
child: Scaffold(
appBar: AppBar(
title: Text("MVVM Example"),
),
body: Center(
child: ViewModelBuilder<MyViewModel>(
builder: (context, viewModel) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(viewModel.title),
ElevatedButton(
onPressed: () {
viewModel.updateTitle("New Title!");
},
child: Text("Update Title"),
),
],
);
},
),
),
),
);
}
}
3. 运行应用
在你的 main.dart
文件中,运行 MyView
:
import 'package:flutter/material.dart';
import 'my_view.dart';
void main() {
runApp(MaterialApp(
home: MyView(),
));
}