我正在尝试为Redux商店使用CoRedux在Android上实现后退按钮处理。我确实找到了一种解决方法,但是我希望有一个更优雅的解决方案,因为我的方法似乎很简单。
问题
问题的核心是返回Android Fragment的事实与第一次呈现该Fragment不同。
[用户第一次访问该片段时,我以FragmentManager
作为事务进行渲染,并为“主”屏幕添加了一个后向堆栈条目
fragmentManager?.beginTransaction() ?.add(R.id.myFragmentContainer, MyFragment1()) ?.addToBackStack("main")?.commit()
当用户从另一个片段返回该片段时,回到该片段的方法是弹出堆栈:
fragmentManager?.popBackStack()
这似乎与Redux原则相冲突,在Redux原则中,状态应足以呈现UI,但在这种情况下,指向状态的路径也很重要。
Hack Solution
我希望有人可以对此解决方案进行改进,但是我设法通过引入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商店的CoRedux在Android上实现后退按钮处理。我确实找到了一种方法来做,但是我希望有一个更优雅的解决方案,因为我的方法似乎很简单。 ...
为了解决此问题,我决定接受不能直接解决冲突的问题。冲突是Redux与Android的本机后退按钮处理之间的冲突,因为Redux需要成为状态的主控者,但Android会保留后退堆栈信息。意识到这两种方法不能很好地结合在一起,我决定放弃Android的后堆栈处理,并在我的Redux商店中完全实现它。