【发布时间】:2019-12-19 01:29:41
【问题描述】:
我正在尝试使用 CoRedux 为我的 Redux 商店在 Android 上实现后退按钮处理。我确实找到了一种方法来做到这一点,但我希望有一个更优雅的解决方案,因为我的似乎是一个 hack。
问题
问题的核心是返回到 Android Fragment 与第一次渲染该 Fragment 不同。
当用户第一次访问 Fragment 时,我将它与 FragmentManager 作为事务渲染,为“主”屏幕添加一个返回堆栈条目
fragmentManager?.beginTransaction()
?.add(R.id.myFragmentContainer, MyFragment1())
?.addToBackStack("main")?.commit()
当用户从另一个fragment返回到那个fragment时,返回的方式是pop back stack:
fragmentManager?.popBackStack()
这似乎与 Redux 原则相冲突,其中状态应该足以呈现 UI,但在这种情况下,状态路径也很重要。
破解解决方案
我希望有人可以改进这个解决方案,但我通过引入一些驻留在 Redux 之外的状态(一个名为 skipRendering 的布尔值)设法解决了这个问题。也许你可以称这种“短暂”状态。初始化为 false,skipRendering 在用户点击返回按钮时设置为 true:
fun popBackStack() {
fragmentManager?.popBackStack()
mapViewModel.dispatchAction(MapViewModel.ReduxAction.BackButton)
skipRendering = true
}
将后退按钮分派到 redux 存储区会将 redux 状态回退到之前的状态,如下所示:
return when (action) {
// ...
ReduxAction.BackButton -> {
state.pastState
?: throw IllegalStateException("More back taps processed than past state frames")
}
}
不管怎样,只要用户请求访问用户随后可以从其中返回的片段,reducer 就会填充pastState。
return when (action) {
// ...
ReduxAction.ShowMyFragment1 -> {
state.copy(pastState = state, screenDisplayed = C)
}
}
最后,如果skipRendering,渲染会跳过处理,因为调用fragmentManager?.popBackStack() 的必要工作是在调度BackButton 操作之前处理的。
我怀疑有更好的解决方案使用 Redux 构造,例如副作用。但我一直在想办法更优雅地解决这个问题。
【问题讨论】:
-
对 redux 不太确定,但你可以通过调用 override fun onBackPressed(){ //code what you want to do here } 覆盖 Android Kotlin 上的后退按钮活跃
-
感谢@RowanBerry,这实际上是我已经在做的。 Activity 覆盖
onBackPressed()并调用上面的Fragment 的popBackStack()函数。抱歉,我没有澄清这一点。 -
标签: android redux android-architecture-components