写点什么

Flutter 退出当前操作二次确认怎么做才更优雅?

作者:岛上码农
  • 2022 年 7 月 03 日
  • 本文字数:1684 字

    阅读完需:约 6 分钟

Flutter 退出当前操作二次确认怎么做才更优雅?

前言

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


发布于: 刚刚阅读数: 3
用户头像

岛上码农

关注

用代码连接孤岛,公众号@岛上码农 2022.03.03 加入

从南漂到北,从北漂到南的业余码农

评论

发布
暂无评论
Flutter 退出当前操作二次确认怎么做才更优雅?_flutter_岛上码农_InfoQ写作社区