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
相关产品推荐
相关产品推荐

