Flutter基于Provider+PageView实现注册页跳过已验证账号步骤问题
实现方案
第一步 修复现有代码的已知错误
你现有代码存在3个逻辑错误,先修正才能正常跑通基础流程:
- 1 邮箱校验逻辑写反
原来的checkUser用every判断,返回true时代表「所有已存用户的邮箱都不等于当前输入值」,也就是邮箱不存在,但你的判断逻辑刚好写反了,改成下面的代码:
validator: (value) { if (value!.isEmpty) { return 'Email address is required'; } else if (!isValid(value)) { return "Email address incorrect"; } // 检查邮箱是否已存在 final inputEmail = value.toLowerCase().trim(); User? matchedUser; // 不用额外导依赖的匹配方式,避免找不到用户时报错 try { matchedUser = context.read<Users>().users.firstWhere((user) => user.userEmail == inputEmail); } catch(e) { matchedUser = null; } // 邮箱存在且已经填完所有信息,提示去登录 if (matchedUser != null && matchedUser.infoFilled) { return "Email address is exist, try Login "; } // 校验通过,保存当前输入邮箱 setState(() { context.read<Users>().emailAddress = inputEmail; }); return null; },
- 2 邮箱页继续按钮的用户匹配逻辑写反
原来的firstWhere判断条件是user.userEmail != 输入邮箱,会匹配到错误的用户,改成如下代码:
onPressed: () { if (!EmailKeys.formKey.currentState!.validate()) { return; } final usersProvider = context.read<Users>(); final matchedUser = usersProvider.users.firstWhere((user) => user.userEmail == usersProvider.emailAddress); // 已验证且没填完信息,直接跳第三页(索引为2) if (matchedUser.isVirified && !matchedUser.infoFilled) { widget.pageController.jumpToPage(2); } else { // 未验证跳验证码页 widget.pageController.nextPage( duration: const Duration(milliseconds: 50), curve: Curves.easeOut, ); } },
- 3 验证码通过后重复创建用户
现在验证码通过直接调用addEmail会重复添加同一邮箱的用户,改成先查是否存在对应邮箱的用户,不存在再创建,存在就更新验证状态:
先修改Users类里的方法,新增更新验证状态的逻辑:
class Users with ChangeNotifier { // ... 原有代码保持不变 // 新增方法:保存邮箱验证状态 void saveVerifiedEmail() { final matchedIndex = users.indexWhere((user) => user.userEmail == emailAddress); if (matchedIndex == -1) { // 没有该用户则新增 users.add(User.email(emailAddress, uuid.v4(), isVirified, infoFilled)); } else { // 已有该用户则更新验证状态 users[matchedIndex].isVirified = true; } notifyListeners(); } }
然后把验证码页的context.read<Users>().addEmail();改成调用saveVerifiedEmail():
onCompleted: (v) { formKey.currentState!.validate(); if (currentCode.length != 5 || currentCode != "55555") { errorController.add(ErrorAnimationType.shake); setState(() { hasError = true; }); } else { setState(() { widget.currentIndex++; final usersProvider = context.read<Users>(); usersProvider.isVirified = true; // 替换原来的addEmail usersProvider.saveVerifiedEmail(); hasError = false; ScreenVerification.verificationEmail = true; widget.pageController.nextPage(duration: const Duration(milliseconds: 10),curve: Curves.easeOut,); }); } },
第二步 增加数据持久化
现在你的用户数据都存在内存中,APP退出后就会清空,所以必须做持久化才能实现退出后重新进入还能识别已验证邮箱的需求,推荐两种快速实现的方案二选一:
- 方案1:用Hive数据库,直接序列化存储
User对象,适合数据结构复杂的场景 - 方案2:用shared_preferences存储已验证但未填完信息的邮箱列表,适合轻量场景
以shared_preferences为例,实现逻辑如下:
- 导入shared_preferences依赖,APP启动时读取已存的未完成注册的用户数据,初始化到
Users类的users列表里 - 每次调用
saveVerifiedEmail、用户填完信息更新infoFilled状态时,同步把最新的用户数据写入持久化存储
第三步 信息填写完成后的状态更新
用户填完第三页及后续的注册信息后,记得更新对应用户的infoFilled为true,同步更新持久化数据,后续用户再输入该邮箱就会提示去登录。
注意:你现有代码里的
isVirified是拼写错误,正确拼写为isVerified,建议全局统一修改避免后续踩坑。
内容的提问来源于stack exchange,提问作者Hasan Alnatour
相关产品推荐
相关产品推荐

