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

Flutter实现类WhatsApp通知点击分状态(冷/热态)导航

解决方案

核心是通过启动标记+OneSignal冷态通知拦截区分两种状态的导航逻辑,彻底解决闪屏页覆盖目标页的问题。

1. 全局标记定义

先定义全局变量用来标记跳转状态、存储通知参数:

// 标记是否需要跳过闪屏页,仅冷态启动时生效
bool shouldSkipSplash = false;
// 存储通知携带的目标页面参数
Map<String, dynamic>? notificationTargetData;

2. 修改main.dart初始化逻辑

在runApp()前完成OneSignal初始化,拦截冷态启动的通知数据:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化OneSignal
  await OneSignal.initialize("YOUR_APP_ID");

  // 处理冷态启动时的通知点击(应用完全关闭后点击通知)
  final OSNotificationOpenedResult? openedResult = await OneSignal.notificationOpened();
  if (openedResult != null) {
    notificationTargetData = openedResult.notification.additionalData;
    // 检查是否有目标页面参数,有则标记跳过闪屏
    if (notificationTargetData?['target_screen'] != null) {
      shouldSkipSplash = true;
    }
  }

  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App Name',
      // 根据标记设置初始路由
      initialRoute: shouldSkipSplash ? '/target' : '/splash',
      routes: {
        '/splash': (context) => const SplashScreen(),
        '/home': (context) => const HomeScreen(),
        '/target': (context) => TargetScreen(
              data: notificationTargetData,
            ),
      },
      // 处理冷态跳转的返回栈逻辑
      onGenerateRoute: (settings) {
        if (settings.name == '/target' && shouldSkipSplash) {
          return MaterialPageRoute(
            builder: (context) => TargetScreen(data: notificationTargetData),
            settings: settings,
          );
        }
        return null;
      },
    );
  }
}

3. 修改SplashScreen的自动跳转逻辑

去掉硬编码的3秒延迟,根据全局标记决定行为:

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

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    _handleNavigation();
  }

  void _handleNavigation() {
    if (!shouldSkipSplash) {
      // 原逻辑:3秒后跳转到首页
      Future.delayed(const Duration(seconds: 3), () {
        Navigator.pushReplacementNamed(context, '/home');
      });
    } else {
      // 跳过闪屏,直接跳目标页,同时保留首页在返回栈
      Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(
          builder: (context) => TargetScreen(data: notificationTargetData),
        ),
        (route) => route.isFirst, // 返回时回到首页
      );
      // 重置标记,避免下次启动误触发
      shouldSkipSplash = false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: Text('Splash Screen')),
    );
  }
}

4. 热态通知点击处理(完善原有逻辑)

在首页初始化时添加热态通知监听,直接跳转目标页:

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

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

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

  void _setupNotificationListener() {
    // 前台/后台点击通知时直接跳转
    OneSignal.notificationOpenedStream.listen((OSNotificationOpenedResult result) {
      final targetData = result.notification.additionalData;
      if (targetData?['target_screen'] != null) {
        Navigator.pushNamed(context, '/target', arguments: targetData);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: const Center(child: Text('Home Screen')),
    );
  }
}

5. 通知API请求参数调整

后端发送OneSignal通知时,需在additional_data中携带目标页面信息,示例请求:

{
  "app_id": "YOUR_APP_ID",
  "include_player_ids": ["USER_PLAYER_ID"],
  "contents": {"en": "New message notification"},
  "additional_data": {
    "target_screen": "target",
    "target_id": "123",
    "target_title": "Message from John"
  }
}

关键注意点

  • 冷态启动时必须在runApp()前完成OneSignal通知数据获取,否则初始路由已设置为闪屏页无法拦截
  • 跳转目标页时要确保返回栈中存在首页,避免返回直接退出应用
  • 全局标记使用后及时重置,防止下次冷启动误触发

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:52:14