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

如何在Flutter中用SharedPreferences实现引导页仅显示一次且非首页

实现方案

核心逻辑是:在应用的实际首页启动时,先读取SharedPreferences的标记,判断是否需要跳转引导页,而非把引导页设为入口页。

步骤1:封装SharedPreferences工具方法(可选,简化代码)

import 'package:shared_preferences/shared_preferences.dart';

class Prefs {
  // 读取是否已看过引导页的标记
  static Future<bool> hasSeenOnboarding() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool('hasSeenOnboarding') ?? false;
  }

  // 标记引导页已查看
  static Future<void> markOnboardingSeen() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('hasSeenOnboarding', true);
  }
}

步骤2:在实际首页中处理跳转逻辑

假设你的应用实际首页是HomeScreen,可以通过两种方式实现跳转判断:

方式一:在首页初始化时检查跳转

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  void initState() {
    super.initState();
    _checkAndNavigateToOnboarding();
  }

  Future<void> _checkAndNavigateToOnboarding() async {
    final hasSeen = await Prefs.hasSeenOnboarding();
    if (!hasSeen) {
      // 使用pushReplacement,避免用户返回时再次进入引导页
      await Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => const OnboardingScreen()),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('应用首页')),
      body: const Center(child: Text('应用主内容区域')),
    );
  }
}

方式二:用FutureBuilder处理加载过渡(更流畅)

如果不想让首页闪一下再跳转,可以用FutureBuilder在加载时显示过渡页面:

class HomeWrapper extends StatelessWidget {
  const HomeWrapper({super.key});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<bool>(
      future: Prefs.hasSeenOnboarding(),
      initialData: false,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          // 加载中显示闪屏或加载动画
          return const Scaffold(body: Center(child: CircularProgressIndicator()));
        }

        final hasSeen = snapshot.data ?? false;
        return hasSeen ? const HomeScreen() : const OnboardingScreen();
      },
    );
  }
}

之后把MaterialApp的home属性设为HomeWrapper即可。

步骤3:引导页中标记已查看

在引导页的完成按钮点击事件里,标记引导页已查看并返回首页:

class OnboardingScreen extends StatelessWidget {
  const OnboardingScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await Prefs.markOnboardingSeen();
            // 替换当前路由,返回首页
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => const HomeScreen()),
            );
          },
          child: const Text('完成引导,进入首页'),
        ),
      ),
    );
  }
}

关键注意事项

  • 跳转时必须用pushReplacement,避免用户按返回键回到引导页。
  • SharedPreferences操作是异步的,不要在build方法中直接调用,避免阻塞UI。
  • 测试时如果需要重置引导页状态,可以调用prefs.remove('hasSeenOnboarding')清除标记。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:22