Firebase动态链接跳转StoreFragment后自动返回HomeFragment求助
解决从登录导航图跳转到主导航图指定Fragment后自动返回startDestination的问题
我之前也碰到过完全一样的坑!问题出在当你通过PendingIntent启动MainActivity时,Navigation组件会自动先加载主导航图的startDestination(也就是homeFragment),之后才会执行你指定的深链接跳转,这就导致视觉上刚进入StoreFragment就被拉回了首页。咱们一步步来修复它:
方案一:通过Intent参数让MainActivity手动控制初始导航
这种方法最直接,不需要修改导航图配置,只需要在登录页传递标记参数,让MainActivity判断是否要直接跳转到StoreFragment:
步骤1:修改登录页的PendingIntent创建代码
不要用createDeepLink().setGraph()的方式,而是直接给Intent添加标记和参数,再生成PendingIntent:
// 准备你的产品参数bundle val bundle = Bundle().apply { putString("product_id", "你的产品ID") // 其他参数... } // 创建指向MainActivity的Intent val intent = Intent(this, MainActivity::class.java).apply { putExtras(bundle) // 添加一个标记,告诉MainActivity这是深链接跳转 putExtra("IS_DEEP_LINK_TO_STORE", true) } // 生成PendingIntent并发送 val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) pendingIntent.send()
步骤2:修改MainActivity的导航初始化逻辑
在MainActivity的onCreate方法中,先判断是否有深链接标记,再决定初始导航的目标,跳过默认的startDestination自动跳转:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_main) as NavHostFragment val navController = navHostFragment.navController val isDeepLinkToStore = intent.getBooleanExtra("IS_DEEP_LINK_TO_STORE", false) val productBundle = intent.extras if (isDeepLinkToStore && productBundle != null) { // 直接导航到StoreFragment,同时传递参数 navController.setGraph(R.navigation.nav_graph_main, productBundle) navController.navigate(R.id.storeFragment, productBundle) } else { // 正常启动,加载默认的startDestination navController.setGraph(R.navigation.nav_graph_main) } }
方案二:利用Navigation的DeepLink配置(更规范)
如果想遵循Navigation组件的最佳实践,可以给StoreFragment配置专属的DeepLink URI,让Navigation自动处理跳转逻辑:
步骤1:在主导航图中添加DeepLink配置
修改nav_graph_main.xml,给StoreFragment添加<deepLink>标签:
<fragment android:id="@+id/storeFragment" android:name="in.indiahaat.feature.main.home.store_screen.StoreFragment" android:label="fragment_store" tools:layout="@layout/fragment_store" > <!-- 保留你原有的action配置 --> <action android:id="@+id/action_storeFragment_pop" app:popUpTo="@id/storeFragment" app:popUpToInclusive="true" /> <action android:id="@+id/storeFragment_to_reportRetailerFragment" app:popUpTo="@id/reportRetailerFragment" app:destination="@id/reportRetailerFragment" /> <!-- 添加DeepLink配置 --> <deepLink app:uri="app://indiahaat/store/{productId}" /> </fragment>
步骤2:登录页生成DeepLink Intent
用URI的方式创建Intent,指向StoreFragment的DeepLink:
val productId = "你的产品ID" // 拼接DeepLink URI val deepLinkUri = Uri.parse("app://indiahaat/store/$productId") val intent = Intent(Intent.ACTION_VIEW, deepLinkUri).apply { setComponent(ComponentName(this@LoginActivity, MainActivity::class.java)) } val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) pendingIntent.send()
步骤3:MainActivity处理DeepLink
在MainActivity中让Navigation处理DeepLink Intent,确保直接跳转到StoreFragment:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navController = findNavController(R.id.nav_host_fragment_main) // 处理DeepLink Intent intent?.let { if (Intent.ACTION_VIEW == it.action && it.data != null) { navController.handleDeepLink(it) } } } // 如果MainActivity的launchMode是singleTask/singleTop,还要重写onNewIntent override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) setIntent(intent) findNavController(R.id.nav_host_fragment_main).handleDeepLink(intent) }
额外注意点
- 检查MainActivity的
launchMode:如果设置了singleTask或singleTop,一定要重写onNewIntent方法处理新的Intent,否则后台的MainActivity无法响应深链接跳转。 - 测试时要确保登录页的PendingIntent使用了正确的
FLAG(比如FLAG_UPDATE_CURRENT),避免旧的Intent参数被缓存。
内容的提问来源于stack exchange,提问作者Kavach Chandra
相关产品推荐
相关产品推荐

