https://kotlinlang.org logo
#compose
Title
# compose
m

Mikołaj Kąkol

02/23/2021, 7:25 PM
it seams that
rememberSaveableStateHolder
is broken in somehow in alpha12. Consider example from here: https://github.com/androidx/androidx/blob/androidx-main/compose/runtime/runtime-sa[…]/compose/runtime/saveable/samples/SaveableStateHolderSamples.kt and change
Copy code
Box(modifier) {
            restorableStateHolder.SaveableStateProvider(currentScreen) {
                content(currentScreen)
            }
       }
to
Copy code
Box(modifier) {
            restorableStateHolder.SaveableStateProvider(currentScreen) {
                Crossfade(targetState = currentScreen) {
                    content(it)
                }
            }
        }
you will notice that animation doesn’t work. If you will remove that state holder:
Copy code
Box(modifier) {
            Crossfade(targetState = currentScreen) {
                content(it)
            }
        }
crossfade works. So either
stateholder
is broken or
crossfade
. From what I unsderstand problem is that Crossfade implementation uses
remember
to store items to render during transition. What I wanted to achieve is some nice animation between screens. What to do? 🤔 🙀
@Adam Powell could you take a look? ☺️
and idea like
Copy code
Crossfade(targetState = currentScreen) {
            Box(modifier) {
                restorableStateHolder.SaveableStateProvider(currentScreen) {
                    content(it)
                }
            }
        }
crashes after screen change with
Copy code
java.lang.IllegalArgumentException: Key screen2 was used multiple times 
        at androidx.compose.runtime.saveable.SaveableStateHolderImpl$SaveableStateProvider$1.invoke(SaveableStateHolder.kt:91)
a

Andrey Kulikov

02/23/2021, 11:28 PM
you need to first call Crossfade and only then SaveableStateProvider
in your last sample you did it almost right, but you are ignoring the parameter which Crossfade gives you in a trailing lambda. please see how it is done in the demo I shared
a

Albert Chang

02/24/2021, 12:21 AM
I think your problem here is that when
currentScreen
changes, instead of recomposing the composable passed to
SaveableStateProvider
, a new composition is created, which means that the
Crossfade
is not the same to the old
Crossfade
thus not working.
m

Mikołaj Kąkol

02/24/2021, 6:14 AM
thank you Andrey, that worked
Copy code
Crossfade(targetState = currentScreen) {
            Box(modifier) {
                restorableStateHolder.SaveableStateProvider(it) {
                    content(it)
                }
            }
        }
amazing :)
91 Views