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

Android多返回栈架构下如何向目标页面传递数据?

解决方案:多返回栈下保留状态并传递新参数

你的核心问题是app:restoreState="true"会恢复B页面栈的原有状态(包括首次进入时的参数),导致新传递的参数被覆盖,同时直接调用setArguments会因为Fragment状态已保存而抛出异常。以下是几种符合需求的解决方案:

方案一:使用共享ViewModel传递参数(推荐)

通过Activity级别的ViewModel共享数据,既不会影响各返回栈的状态保存,又能传递新参数,完全适配你的需求。

步骤1:定义共享ViewModel

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class SharedNavViewModel : ViewModel() {
    // 用于传递需要更新的参数
    val updatedInformationInt = MutableLiveData<Int>()
}

步骤2:C页面跳转时设置参数

在C页面的按钮点击事件中,先给ViewModel设置参数,再执行导航:

val sharedViewModel = ViewModelProvider(requireActivity())[SharedNavViewModel::class.java]
// 设置要传递的新参数
sharedViewModel.updatedInformationInt.value = 456
// 执行导航(使用原Action即可,无需修改restoreState)
findNavController().navigate(R.id.action_C_to_B)

步骤3:B页面监听参数变化

在B页面的onViewCreated中监听ViewModel的参数更新,处理新数据:

val sharedViewModel = ViewModelProvider(requireActivity())[SharedNavViewModel::class.java]
sharedViewModel.updatedInformationInt.observe(viewLifecycleOwner) { newInt ->
    // 这里处理新参数,比如更新UI、执行业务逻辑
    // 注意:首次进入时如果没有设置过参数,LiveData可能不会触发,可根据需求设置默认值
}

优势:

  • 完全保留各返回栈的原有状态(如滚动位置、输入内容)
  • 避免setArguments的异常问题
  • 符合Jetpack组件的架构设计规范

方案二:临时关闭状态恢复(不推荐,仅适合无需保留状态的场景)

如果某些场景下可以接受重置B栈的状态,可在跳转时动态设置restoreState=false,让新参数生效:

val navOptions = NavOptions.Builder()
    .setRestoreState(false) // 本次跳转不恢复原有状态
    .setPopUpTo(R.id.destination_A, true)
    .setPopUpToSaveState(true)
    .build()

findNavController().navigate(
    R.id.action_C_to_B,
    bundleOf("informationInt" to 789),
    navOptions
)

缺点:会丢失B栈之前的所有状态,不符合你“保留各返回栈状态”的核心需求。

方案三:结合SavedStateHandle实现持久化参数传递

如果需要参数在进程重启后依然保留,可使用SavedStateHandle扩展ViewModel:

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel

class PersistentSharedViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    companion object {
        private const val KEY_INFO_INT = "information_int"
    }

    fun setInformationInt(value: Int) {
        savedStateHandle[KEY_INFO_INT] = value
    }

    fun getInformationInt() = savedStateHandle.getLiveData<Int>(KEY_INFO_INT)
}

使用方式和方案一一致,只是数据会被持久化到SavedState中,进程重启后不会丢失。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:25:38