You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter登出后界面不刷新问题求助(已尝试常见方案)

问题修复:Flutter登出后界面不更新

核心问题分析

  1. 状态类设计错误:PreferencesState继承了ChangeNotifier,但搭配StateNotifierProvider时,状态类应为纯不可变数据类,StateNotifier本身负责状态更新的通知逻辑,状态类无需再继承ChangeNotifier,否则会导致通知逻辑混乱。
  2. 登出逻辑顺序颠倒:当前代码先执行登出操作再弹出确认弹窗,用户取消确认时已完成登出,且重复调用clearUserData,逻辑完全错误。
  3. 多余的通知调用:在setUserData和clearUserData中调用state.notify()无效且多余,StateNotifier更新state时会自动触发所有监听者重建。

分步修复

1. 修正状态类与Notifier实现

将PreferencesState改为纯数据类,移除ChangeNotifier继承,简化PreferencesNotifier逻辑:

final preferencesProvider = StateNotifierProvider<PreferencesNotifier, PreferencesState>(
  (ref) => PreferencesNotifier(),
);

// 纯数据类,仅存储状态数据
class PreferencesState {
  final UserModel? user;
  final bool allowNotification;

  PreferencesState({this.user, this.allowNotification = true});

  PreferencesState copyWith({UserModel? user, bool? allowNotification}) {
    return PreferencesState(
      user: user ?? this.user,
      allowNotification: allowNotification ?? this.allowNotification,
    );
  }
}

class PreferencesNotifier extends StateNotifier<PreferencesState> {
  final Preferences prefs = Preferences();
  PreferencesNotifier() : super(PreferencesState());

  void setUserData(Map<String, dynamic> json) {
    prefs.setUserData(json);
    // 更新state即可,StateNotifier自动通知监听者
    state = state.copyWith(user: UserModel.fromJson(json));
  }

  void clearUserData() async {
    await prefs.clearUserData(); // 确保异步清理完成再更新状态
    state = state.copyWith(user: null);
  }

  void setAllowNotifications(bool value) {
    prefs.setAllowNotifications(value);
    state = state.copyWith(allowNotification: value);
  }
}

2. 修正登出逻辑顺序

将登出操作移到弹窗确认回调中,避免提前执行登出:

void cerrarSesion(WidgetRef ref, BuildContext context) async {
  CustomAlertDialog.showAlertDialog(
    context, 
    'Cerrar Sesión', 
    '¿Seguro desea cerrar sesión?', 
    () async {
      // 用户确认后再执行完整登出流程
      final bool isGoogleSigned = await ref.read(userDatasourceProvider).isGoogleSigned();
      await ref.read(userSignInProvider.notifier).signOut(isGoogleSigned);
      await ref.read(preferencesProvider.notifier).clearUserData();
    }, 
    null
  );
}

3. 确保Stateful Shell Branch页面响应状态变化

如果使用StatefulShellBranch存在路由缓存问题,可在SettingsView中添加状态监听,强制页面响应变化:

@override
Widget build(BuildContext context, WidgetRef ref) {
  // 监听用户状态变化,确保页面及时响应
  ref.listen<PreferencesState>(preferencesProvider, (previous, next) {
    // 若路由缓存导致页面未刷新,可手动触发路由重建
    // Navigator.of(context).popAndPushNamed('/settings');
  });

  UserModel? user = ref.watch(preferencesProvider).user;
  bool logged = (user != null);

  return SafeArea(
    child: CustomScrollView(
      slivers: [
        SliverToBoxAdapter(
          child: UserCard(user: user),
        ),
        logged ? LoggedSettingsItems(user: user) : const GuestSettingsItems(),
      ],
    ),
  );
}

验证要点

  • 登录时确认user状态正确更新并触发页面重建
  • 登出时确认弹窗后,检查preferencesProvider的user是否变为null,并切换到GuestSettingsItems

内容的提问来源于stack exchange,提问作者DaSe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 01:18:21