bluelinelabs / bluelinelabs/Conductor
[Question] Force controller recreate its view after returning from backstack
- Dominant language
- Java
- Stars
- 3.9k
- Forks
- 338
- PR merge metrics
- No merged PRs in 30d
Description
I'm trying to rearrange the backstack by extracting the sublist from it and moving this sublist to the top. I created this extension function for this purpose:
```Kotlin
/*
* Find a backstack sublist in range from [fromTranstactionIndex] to [toTranstactionIndex]
* and move it to the end of backstack, so the topmost controller of that sublist
* is now the head of the backstack.
*
* Example.
* We call this function with next parameters:
* [fromTranstactionIndex] == 1, [toTranstactionIndex] == 3.
*
* Backstack before function call:
* [0] --- ProfileController
* [1] -*- ShopController
* [2] -*- ShopFeedController
* [3] -*- ShopFeedPeriodSelectionController
* [4] --- BookmarksController
*
* Backstack after function call:
* [0] --- ProfileController
* [1] --- BookmarksController
* [2] -*- ShopController
* [3] -*- ShopFeedController
* [4] -*- ShopFeedPeriodSelectionController
*/
fun Router.pullSubstackUp(fromTranstactionIndex: Int, toTranstactionIndex: Int,
changeHandler: ControllerChangeHandler? = null): Boolean {
// The result backstack to push into router.
var newBackstack: MutableList? = null
if (fromTranstactionIndex != -1 && toTranstactionIndex != -1) {
// 1. Extract the specified range from backstack.
newBackstack = backstack.toMutableList()
val substack = newBackstack.subList(fromTranstactionIndex, toTranstactionIndex + 1).toMutableList()
newBackstack.minusAssign(substack)
// 2. Add extracted range to the top of new backstack.
newBackstack.addAll(substack)
}
if (newBackstack != null) {
setBackstack(newBackstack, changeHandler)
return true
}
return false
}
```
It works, but the view of the topmost controller becomes empty. It is recreated only after screen rotation, when configuration change forces to recreate the view.
After debugging it I figured, that topmost controller, moved up from the backstack, receives the old `container` instance in the `onCreateView(inflater: LayoutInflater, container: ViewGroup)`. My thIs cause an empty view?
How can I force controller to clear reference to the view after it is detached?
---------------
Usecase explanation:
Need to re-open controllers, opened from bottom navigation bar, with preserving their order. Meaning, when user returns to the previously opened tab in bottom navigation bar, he should be brought to the exact same controller with exact same state that was when he leaved this tab. If this is impossible (e. g., backstack is cleared), only then the topmost controller can be created again.
Related to #241 and #295
Contributor guide
Research direction
Start with Router.setBackstack and the controller view lifecycle around onCreateView, then reproduce the supplied pullSubstackUp extension with the bottom-navigation use case. Compare the moved controller's container and view state before and after returning from the backstack. Done means the restored controller shows its existing state or is safely recreated instead of displaying an empty view.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100