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

Flutter自定义启动页无更新时无法自动跳转对应页面如何修复?

问题修复:Flutter闪屏页无更新时无法跳转页面

问题描述

开发自定义闪屏启动页,需求如下:

  • 检查应用是否存在新版本,有更新则强制显示弹窗提示用户更新
  • 无更新时,根据SharedPreference存储的用户角色自动跳转至对应页面

当前问题:检测到更新时弹窗正常显示,但无更新时无法完成页面跳转。

问题代码

_checkUpdate() async {
  DocumentSnapshot versionDetails = await FirebaseFirestore.instance
      .collection('xyz')
      .doc('abc')
      .get();
  if (currentVersion != versionDetails['latestVersion']) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => PopScope(
        child: AlertDialog(
          title: Text(
            'A newer version of the app is available. Please download to continue.',
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          ),
          actions: [
            ElevatedButton(
              onPressed: () async {
                String googleUrl =
                    'https://www.youtube.com/watch?v=dQw4w9WgXcQ';

                final Uri _url = Uri.parse(googleUrl);
                try {
                  await launchUrl(_url);
                } catch (e) {
                  Fluttertoast.showToast(msg: 'Error');
                }
              },
              child: Text('Download'),
            ),
          ],
          actionsAlignment: MainAxisAlignment.center,
        ),
      ),
    );
  } else {
    Scaffold(
      body: FutureBuilder(
        future: UserSharedPreference.getUserRole(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == '') {
            goToDisableBack(context, LoginScreen());
          } else if (snapshot.data == 'wife') {
            goToDisableBack(context, BottomPage());
          } else if (snapshot.data == 'volunteer') {
            goToDisableBack(context, VolunteerHomeScreen());
          } else if (snapshot.data == 'husband') {
            goToDisableBack(context, HusbandHomeScreen());
          }
          return progressIndicator(context);
        },
      ),
    );
  }
}

@override
void initState() {
  _checkUpdate();
  super.initState();
}

@override
Widget build(BuildContext context) {
  return Scaffold();
}

....

void goToDisableBack(BuildContext context, Widget nextScreen) {
  Navigator.pushReplacement(
    context,
    MaterialPageRoute(
      builder: (context) => nextScreen,
  ));
}

问题原因

  1. 无效Widget构建:else分支中直接创建的Scaffold和FutureBuilder不会被渲染——initState中的异步函数无法影响build方法返回的空Scaffold,导致跳转逻辑根本不执行。
  2. 导航时机错误:在FutureBuilder的builder回调中直接调用Navigator,违反Flutter Widget生命周期规则,可能引发异常或无响应。
  3. 空值未处理:未考虑getUserRole()返回null的情况,存在空指针风险。

修复方案

修改_checkUpdate函数的else分支,移除无用的Widget构建,调整导航时机并增强鲁棒性:

修改后的核心代码

_checkUpdate() async {
  try {
    DocumentSnapshot versionDetails = await FirebaseFirestore.instance
        .collection('xyz')
        .doc('abc')
        .get();
    if (currentVersion != versionDetails['latestVersion']) {
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => PopScope(
          canPop: false, // 更符合PopScope的API规范
          child: AlertDialog(
            title: Text(
              '发现新版本,请下载后继续使用',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 20),
            ),
            actions: [
              ElevatedButton(
                onPressed: () async {
                  String googleUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
                  final Uri _url = Uri.parse(googleUrl);
                  try {
                    await launchUrl(_url);
                  } catch (e) {
                    Fluttertoast.showToast(msg: '打开链接失败');
                  }
                },
                child: Text('立即下载'),
              ),
            ],
            actionsAlignment: MainAxisAlignment.center,
          ),
        ),
      );
    } else {
      // 直接异步获取用户角色
      String? role = await UserSharedPreference.getUserRole();
      // 延迟导航,确保当前页面构建完成
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (role == null || role.isEmpty) {
          goToDisableBack(context, LoginScreen());
        } else if (role == 'wife') {
          goToDisableBack(context, BottomPage());
        } else if (role == 'volunteer') {
          goToDisableBack(context, VolunteerHomeScreen());
        } else if (role == 'husband') {
          goToDisableBack(context, HusbandHomeScreen());
        }
      });
    }
  } catch (e) {
    // 处理请求失败情况,默认跳转到登录页
    WidgetsBinding.instance.addPostFrameCallback((_) {
      goToDisableBack(context, LoginScreen());
    });
  }
}

@override
Widget build(BuildContext context) {
  // 闪屏页显示加载指示器,给用户视觉反馈
  return Scaffold(
    body: Center(child: progressIndicator(context)),
  );
}

关键修改点

  • 移除无效Widget:删除else分支中不会被渲染的Scaffold和FutureBuilder,直接在异步逻辑中获取角色。
  • 安全导航时机:用WidgetsBinding.instance.addPostFrameCallback延迟执行导航,避免生命周期冲突。
  • 异常处理:添加try-catch包裹异步逻辑,处理网络请求或本地存储读取失败的情况。
  • 闪屏页优化:build方法返回带有加载指示器的Scaffold,提供加载状态反馈。
  • API规范调整:将barrierDismissible替换为PopScope的canPop: false,符合Flutter新版本API要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:00:20