-
-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
navigator.pop() followed by navigator.push(screen) does not dispose the ScreenModel from the popped screen #437
Comments
I will have to take a look on this. We have a |
The way that Voyager disposes the Screens and ViewModel/ScreenModel is the next tick of the composition when the event is a dispose event, when you do We have introduce a new way of handling disposing for Transition API that is still experimental, it does not relay on the The docs are here: https://voyager.adriel.cafe/transitions-api/ We are considering replace the StepDisposable with this approach if is stable enough. |
I tried upgrading to |
Try to use uniqueScreenKey instead |
ah I didn't realise |
I realised this issue was because I had the key as |
Can someone write the steps to solve this |
This really helped me, thank you. If I add a delay in between the
This works, but because of the delay, even thought it's tiny (just 1 millisecond), the screen flickers, at least in my use case, it doesn't look very nice. @DevSrSouza Is there an API we could use to dispose a screen model manually? Without needing a delay? I have tried using the link you provided, but I don't use transitions on Desktop, I present my screens side-by-side instead. I also tried setting |
Hello! A little late to the discussion but I've found a solution that acts as import cafe.adriel.voyager.core.stack.Stack
fun <Item> Stack<Item>.replaceUntil(item: Item, predicate: (Item) -> Boolean) {
val items = items.takeUntilInclusive(predicate) + item
this.replaceAll(items)
}
fun <T> List<T>.takeUntilInclusive(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) {
result.add(item)
if (predicate(item)) break
}
return result
} Due to how voyager works internally the items inserted into the |
Describe the bug
I have been trying to figure out why my screenModel retains its state and data after the screen is popped and the screenModel should be disposed, I have my screen defined as this:
Then if I navigate from ScreenA to ScreenB, I see the "Created ScreenBViewModel" Log
Then if I navigate back (either with system back button or my
onNavigateBack
callback I do see the "Disposed ScreenBViewModel" (this is as expected)however if, while on ScreenB, I call my
onNavigateScreenC
callback I do not see the "Disposed ScreenBViewModel" and then if I navigate back to ScreenA and then forward into ScreenB again I do not see the "Created ScreenBViewModel" Log meaning that this is still using the previous instance that should have been disposed.in Testing I have found that if I replace the
navigator.pop() navigator.push(ScreenC(id))
with
navigator.replace(ScreenC(id))
then the ScreenModel is disposed correctly which is fine for this example but in other places I may need to pop 2 or 3 times before pushing a new screen, and I need to screenModel(s) to be disposed correctly in those instances
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I would expect that is I pop a screen, then it's associated ScreenModel should be disposed. Even if that pop is immediately followed by a push.
Voyager module and version:
voyager-navigator:1.0.0
voyager-screenmodel:1.0.0
voyager-tab-navigator:1.0.0
voyager-transitions:1.0.0
voyager-koin:1.0.0
Koin module and version:
koin-bom:3.5.3
koin-core
koin-compose
koin-android
Snippet or Sample project to help reproduce
See code snippet above
The text was updated successfully, but these errors were encountered: