}
}
网络层的相关代码就不再贴出,感兴趣的可以在本文末尾下载源码进行查看。
由上面代码可知,当View
层触发登录时,调用了Control
层login
接口,在该接口内,实现了展示loading状态,并等待登录的网络请求,当请求完成后,则取消loading状态,最终交给View
层进行数据处理,相关处理的代码如下所示
_login() async {
String name = _nameController.text;
String password = _passwordController.text;
await Con.instance.login(this, name, password);
if (Con.userBean != null) {
NavigatorUtil.goHome(context, Con.userBean);
} else {
ToastUtil.showToast(‘登录失败,请重新登录’);
}
}
到此,MVC整个框架的登录流程已进行完成。
MVP
该架构是在进行Android开发时,是一种比较常用的架构。
架构视图
程序入口
main.dart
是程序的入口,完成登录界面的启动,相关代码如下所示
void main() => runApp(MVPApp());
class MVPApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.black,
),
home: LoginPage(),
);
}
}
登录流程
与MVC
一致,可以参考MVC
。
文本监听
与MVC
一致,可以参考MVC
。
清空账号输入框
与MVC
一致,可以参考MVC
。
密码是否可见
与MVC
一致,可以参考MVC
。
触发登录
View
层点击登录按钮,触发Presenter
层登录逻辑,在Presenter
层通过View
层提供的接口来控制loading界面的展示和隐藏,loading UI相关代码如下所示
Offstage(
offstage: !isLoading,
child: new Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black54,
child: new Center(
child: SpinKitCircle(
color: Theme.of(context).primaryColor,
size: 25.0,
),
),
),
),
上面代码中的isLoading
状态已在基类中做了统一封装,下面对MVP
做定义封装。
封装View层
触发网络请求,需要满足展示和隐藏loading界面,所以View
的对外需要提供这两个最基本的接口,如下面代码所示
abstract class IBaseView {
showLoading();
hideLoading();
}
封装Presenter层
Presenter
层的公共接口只需提供对View
层的注册以及反注册,如下面代码所示
abstract class IBasePresenter {
void onAttachView(V view);
void onDetachView();
}
下面对Presenter
层的代码实现上面所提供的接口,如下面代码所示
abstract class BasePresenter extends IBasePresenter {
V view;
@override
void onAttachView(IBaseView view) {
this.view = view;
}
@override
void onDetachView() {
this.view = null;
}
}
封装State基类
在State
基类中,需要提供Presenter
的初始化的方法、loading状态、数据初始化以及视图的构建等,如下面代码所示
abstract class BaseState<T extends StatefulWidget, P extends BasePresenter,
V extends IBaseView> extends State implements IBaseView {
P presenter;
bool isLoading = false;
P initPresenter();
Widget buildBody(BuildContext context);
void initData() {
}
@override
void initState() {
super.initState();
presenter = initPresenter();
if (presenter != null) {
presenter.onAttachView(this);
}
initData();
}
@override
void dispose() {
super.dis