如何创建通用Dart库,实现可复用的Flutter身份认证功能
解决方案
这个需求完全可以实现,不需要传递类,通过函数回调/构造器参数的方式即可解耦公共库和上层业务页的依赖,以下是两种常用实现方案:
方案1:登录成功后将控制权交还给上层调用方(耦合度最低,推荐)
思路:LoginPage只处理登录逻辑,不负责跳转,登录成功后通过回调通知上层,上层自行处理状态更新和页面跳转逻辑。
第一步 修改公共库LoginPage定义
class LoginPage extends StatefulWidget { // 登录成功回调 final VoidCallback onLoginSuccess; // 可选:登录失败回调 final Function(String errorMsg)? onLoginFailed; const LoginPage({ super.key, required this.onLoginSuccess, this.onLoginFailed, }); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { final _auth = FirebaseAuth.instance; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("身份认证"), ), body: SafeArea( // ... 原有登录表单逻辑 child: () { if (userCredential != null) { setState(() { _isLoading = false; }); // 触发成功回调,关闭当前登录页 widget.onLoginSuccess(); Navigator.pop(context); } else { // 触发失败回调 widget.onLoginFailed?.call("登录失败,请检查账号密码"); } }(), ), ); } }
第二步 上层应用调用修改
以app1.dart为例,app2.dart修改逻辑完全一致:
import 'package:myLibrary/login_page.dart'; class App1 extends StatefulWidget { @override _App1State createState() => _App1State(); } class _App1State extends State<App1> { bool authenticated = false; @override Widget build(BuildContext context) { if (authenticated) { return Scaffold(...); // 应用主页逻辑 } else { return Scaffold( body: Center( child: ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => LoginPage( // 登录成功后更新本地认证状态 onLoginSuccess: () { setState(() { authenticated = true; }); // 可选:此处可添加本地存储认证状态、初始化用户信息等业务逻辑 }, onLoginFailed: (errorMsg) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(errorMsg)), ); }, ), ), ); }, child: const Text("去登录"), ), ), ); } } }
方案2:给LoginPage传递目标页构造器
如果希望跳转逻辑封装在LoginPage内部,可以给LoginPage传一个WidgetBuilder类型的参数,指定登录成功后跳转的页面:
公共库LoginPage修改
class LoginPage extends StatefulWidget { final WidgetBuilder successPageBuilder; const LoginPage({ super.key, required this.successPageBuilder, }); @override _LoginPageState createState() => _LoginPageState(); } // 登录成功逻辑处修改为: if (userCredential != null) { setState(() { _isLoading = false; }); Navigator.pushReplacement( context, MaterialPageRoute( builder: widget.successPageBuilder, ), ); }
上层调用示例
// app1中调用 LoginPage( successPageBuilder: (context) => const App1HomePage(), ) // app2中调用 LoginPage( successPageBuilder: (context) => const App2HomePage(), )
优化提示
你原有代码中在build方法里直接执行Navigator.push逻辑不符合Flutter开发规范,会导致页面重复跳转、构建异常,建议把跳转逻辑放到initState或者用户点击事件的回调中执行。
内容的提问来源于stack exchange,提问作者SpeedyVV
相关产品推荐
相关产品推荐

