Is it possible to persist a snackbar across a devi...
# compose
b
Is it possible to persist a snackbar across a device rotation? I assume that by using:
Copy code
val scope = rememberCoroutineScope()
val scaffoldState = rememberScaffoldState()
That is not going to happen as these are not “rememberSavable”
I guess the first question is, should snackbars be preserved across device rotations?
a
there are two answers here depending on whether you're doing a partial compose integration or a compose-first app
if you're doing a compose-first app, autocomplete every known configuration change into the
configChanges
attribute of your activity tag in your manifest, because compose will react and update granularly for any of them anyway so you don't need activity recreation at all
❤️ 3
👍 6
😮 2
K 2
👍🏾 2
and then the problem goes away entirely
if you're keeping activity recreation, you can hoist a
SnackbarHostState
into a
ViewModel
or similar and pass it to the snackbar presentation you use; the data will persist along with the
SnackbarHostState
of course this also implies that anything you're
showSnackbar
-ing about is similarly scoped to a CoroutineScope that will survive, or those calls will simply remove themselves from the snack queue when their scopes get cancelled
b
Sorry for my ignorance, assuming “compose-first app” means every activity is presenting its UI with compose? Currently I am migrating as I go. I have a couple activities that are built using compose.
a
I suppose a better term would be a compose-first activity; you can make this decision per-activity in your app
the key question is: are you relying on any Views in that activity picking up different resource values in a configuration change? If so, you're probably still relying on activity recreation to do that.
(or fragments, or whatever)
b
Yeah I suppose a theme change from light to dark
Just gathering from your answers that is seems snackbar persistence across configuration changes is not something that is very common… Have not looked at sample application yet, shame on me for sure. But guessing those do not persists something like an “UNDO” snackbar/action across config changes.
I get that this is entirely up to the app developer, but if this is not standard for android app development, then users will know not to expect this behavior
a
I would persist it across config changes, personally. It's kind of frustrating for a user if they lose the ability to undo because they accidentally twisted their hand far enough to rotate the screen.
b
HAHA, yeah that was my initial take during testing. Just surprised that remembering that state across a config change was not more “out of the box” with compose
a
doing it silently/by default is a pretty dangerous thing for compose to do. The code you end up writing for things like this is so lambda-heavy that it's really easy to accidentally capture a reference to something that points back to an activity instance somewhere, which then becomes stale.
We briefly explored making anything you
remember
persist ViewModel-style by default; that ended quickly when we worked through the implications. 🙂
b
HAHA, yes ok I get that
a
sometimes that little speed bump sets the right expectations
b
For me, since my entire presentation is built with compose for my activity, I think this is the right answer. https://kotlinlang.slack.com/archives/CJLTWPH7S/p1622217146183800?thread_ts=1622216960.183000&cid=CJLTWPH7S
👍 1
a
it'll make your life a lot simpler 🙂
we didn't think it was really worth introducing a new concept in compose for this when AAC ViewModel already exists for mixed activities and plain
remember {}
just works for compose-first activities
b
That is something very subtle I didn’t realize and very important. “because compose will react and update granularly for any of them anyway so you don’t need activity recreation at all”. Handling your own configuration changes before compose was icky at best. But if compose is going to handle those this is a nice trick.
Adam, thanks a ton for spending some time on this with me, truly appreciated!
👍 1