美文网首页Android开发Flutter圈子Flutter 入门与实战
退出操作二次确认怎么做代码才更优雅 —— BLoC轻松解决

退出操作二次确认怎么做代码才更优雅 —— BLoC轻松解决

作者: 岛上码农 | 来源:发表于2022-04-05 10:26 被阅读0次

    前言

    在 flutter_bloc提供了一个状态监听组件 BlocListener,当状态发生改变时会调用listener参数给定的回调函数,这个方法没有返回值,可以用于我们处理一些提醒,例如显示弹窗提醒或确认,显示状态信息等等。有了 BlocListener,相当于给我们提供了一个额外处理对象变化的入口。接下来我们通过BlocListener实现某些 App退出登录前的二次确认。

    登录状态

    为了简化逻辑,我们的登录数据只有一个枚举 LoginStatus,有三个状态:

    • logon:已登录
    • logout:已退出登录
    • logoutConfirm:退出登录确认
    
    enum LoginStatus { logon, logout, logoutConfirm }
    
    class LoginCubit extends Cubit<LoginStatus> {
      LoginCubit({initial = LoginStatus.logout}) : super(initial);
    
      void login() => emit(LoginStatus.logon);
      void logout() => emit(LoginStatus.logout);
      void logoutConfirm() => emit(LoginStatus.logoutConfirm);
    }
    

    业务逻辑

    我们在屏幕中央放置一个按钮,根据登录状态切换按钮文本:

    • 已登录:显示为退出登录;
    • 已退出登录:显示为登录。

    点击退出登录按钮的时候,弹出二次确认对话框,确认后更改状态为已退出登录,否则保持登录状态不变,对话框如下图所示。


    退出确认

    代码实现

    由于我们按钮和 BlocListener 都需要使用状态数据,因此使用 BlocProvider 放置在上层为 BlocListenerBlocBuilder 同时提供状态数据。

    class BlocListenerWrapper extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return BlocProvider(
          create: (_) => LoginCubit(),
          child: BlocListenerDemo(),
        );
      }
    }
    

    BlocListener 部分的代码如下:

    class BlocListenerDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('BlocListener 示例'),
          ),
          body: Center(
            child: BlocListener<LoginCubit, LoginStatus>(
              listener: (context, loginSatus) async {
                if (loginSatus == LoginStatus.logout ||
                    loginSatus == LoginStatus.logon) {
                  ScaffoldMessenger.of(context)
                    ..hideCurrentSnackBar()
                    ..showSnackBar(SnackBar(
                      content:
                          Text(loginSatus == LoginStatus.logout ? '已退出登录' : '登录成功'),
                      duration: Duration(seconds: 1),
                    ));
                } else {
                  var confirmed = await _confirmLogout(context);
                  if (confirmed == true) {
                    context.read<LoginCubit>().logout();
                  }
                }
              },
              child: BlocBuilder<LoginCubit, LoginStatus>(
                builder: (context, loginSatus) => TextButton(
                  child: Text(
                    loginSatus == LoginStatus.logon ? '退出登录' : '登录',
                    style: TextStyle(
                      fontSize: 24.0,
                    ),
                  ),
                  onPressed: () {
                    if (loginSatus == LoginStatus.logon) {
                      context.read<LoginCubit>().logoutConfirm();
                    } else {
                      context.read<LoginCubit>().login();
                    }
                  },
                ),
              ),
            ),
          ),
        );
      }
    

    当状态是已登录和已退出登录时显示一个 SnackBar 提示结果,而如果是确认登录,则弹出一个对话框。对话框会返回 truefalse,如果是 true 则表示确认退出,此时再调用 LoginCubitlogout 退出登录。源码已提交至:BLoC状态管理源码,运行效果如下:

    运行效果

    总结

    可以看到,有了BlocListener,我们可以实现类似后置拦截器的效果,在状态改变后做一些额外的的处理,比如提示信息,或者是做数据的上传、离线存储等。通过这种方式处理,可以降低业务代码的耦合度。

    相关文章

      网友评论

        本文标题:退出操作二次确认怎么做代码才更优雅 —— BLoC轻松解决

        本文链接:https://www.haomeiwen.com/subject/ozhksrtx.html