MVC、MVP、BloC、Redux四种架构在Flutter上的尝试

个人博客

前言

从进行开发OpenGit_Flutter项目以来,在项目中选择哪种架构困扰了很久。近段时间,分别在项目中尝试了BloCRedux这两种架构,通过开发中遇到的问题,已经找到了合适的方案。为了演示方便,我选择了该项目的登录流程来为大家做演示,下面对登录流程做下拆解。

  1. 登录首先需要输入账号和密码,只有在账号和密码都有输入的时候,底部登录按钮才能点击,所以需要监听账号和密码输入框的输入状态,用来控制登录按钮的点击状态;
  2. 账号输入框需要支持一键删除的功能;
  3. 密码输入框需要支持对密码可见的功能;
  4. 点击登录按钮触发登录逻辑,在登录过程中需要展示loading界面,当登录失败后,取消loading界面,并进行toast提示;当登录成功之后,跳转的主界面,展示用户的基本信息;
  5. 用户资料和token等信息的保存,在本文中不会提到,如需查看该部分代码,点击OpenGit_Flutter

最终的演示效果如下所示
image
image

登录界面的布局代码,不做过多的介绍,如果需要了解更多,可以查看相关源码,地址会在本文的最后贴出。

工程结构

flutter_architecture根目录是一个Flutter Package,其下面分别创建了blocmvcmvpredux四个工程,lib目录分别是四个工程的公用模块,例如网络请求、日志打印、toast提示、主页信息展示等。如下图所示
image

MVC

该架构是在写flutter_architecture例子时最后加上的,因为在进行Android开发的过程中,经常用它来与MVP做对比。

架构视图

image

程序入口

main.dart是程序的入口,完成登录界面的启动,相关代码如下所示

void main() => runApp(MVCApp());

class MVCApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.black,
      ),
      home: LoginPage(),
    );
  }
}

登录流程

由于登录状态涉及到界面相关控件的刷新,所以继承的是StatefulWidget

文本监听

文本监听需要监听账号和密码输入框的输入状态,需声明两个TextEditingController对象,相关代码如下所示

final TextEditingController _nameController = new TextEditingController();
final TextEditingController _passwordController = new TextEditingController();

initState处理输入框的监听事件,当输入状态改变时,并刷新页面,更新登录按钮状态,相关代码如下所示

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

    _nameController.addListener(() {
      setState(() {});
    });
    _passwordController.addListener(() {
      setState(() {});
    });
}

登录按钮状态判断需要通过账号和密码输入字符串长短来判断,当长度都大于0的时候,按钮才能点击,逻辑层相关代码如下所示

_isValidLogin() {
    String name = _nameController.text;
    String password = _passwordController.text;

    return name.length > 0 && password.length > 0;
}

登录按钮UI层代码如下所示

Align _buildLoginButton(BuildContext context) {
    return Align(
      child: SizedBox(
        height: 45.0,
        width: 270.0,
        child: RaisedButton(
          child: Text(
            '登录',
            style: Theme.of(context).primaryTextTheme.headline,
          ),
          color: Colors.black,
          onPressed: _isValidLogin()
              ? () {
                  _login();
                }
              : null,
          shape: StadiumBorder(side: BorderSide()),
        ),
      ),
    );
}
清空账号输入框

清空输入框只需调用TextEditingController clear方法,如下面代码所示

  TextFormField _buildNameTextField() {
    return new TextFormField(
      controller: _nameController,
      decoration: new InputDecoration(
        labelText: 'Github账号:',
        suffixIcon: new GestureDetector(
          onTap: () {
            _nameController.clear();
          },
          child: new Icon(_nameController.text.length > 0 ? Icons.clear : null),
        ),
      ),
      maxLines: 1,
    );
  }
密码是否可见

密码是否可见主要是通过更新变量_obscureText实现,点击事件处理逻辑很简单,只是对_obscureText做下取反操作,并刷新页面,代码如下所示

TextFormField _buildPasswordTextField(BuildContext context) {
    return new TextFormField(
      controller: _passwordController,
      decoration: new InputDecoration(
        labelText: 'Github密码:',
        suffixIcon: new GestureDetector(
          onTap: () {
            setState(() {
              _obscureText = !_obscureText;
            });
          },
          child:
              new Icon(_obscureText ? Icons.visibility_off : Icons.visibility),
        ),
      ),
      maxLines: 1,
      obscureText: _obscureText,
    );
}
触发登录

View层点击登录按钮,触发Control层登录逻辑,在Control层通过state控制loading界面的展示和隐藏,而loading的最终状态是由Model层的loading状态决定,loading UI相关代码如下所示:

Offstage(
    offstage: !Con.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,
                ),
            ),
    ),
),
定义Control层

首先创建单例对象,并初始化Model层数据,向View层提供登录、加载状态、用户资料等状态的接口,相关代码如下所示


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值