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

Stylianos Gakis

08/26/2022, 2:40 PM
Reading through the per-app language documentation, there’s a part which says “Note that calling
setApplicationLocales()
recreates your
Activity
, unless your app handles locale configuration changes by itself.” Now I remember reading some discussions here, like this one where @Adam Powell suggests that compose handles those itself anyway. Shouldn’t that mean that the documentation should reflect this behavior if it’s also the case for this config change too? It’d be great to know that directly from there without needing to be part of this slack channel.
m

Michael Paus

08/26/2022, 2:49 PM
But that would only work if you have a pure Compose app and you have configured the suppression of the activity recreation in the manifest of that app, which will not be the case for all apps automatically.
s

Stylianos Gakis

08/26/2022, 2:56 PM
“Pure compose app” I wonder what this means actually. If it’s a multi-activity app, this would apply if for that specific activity you only had compose on and fill the list of
configChanges
right? If it’s not only compose, does it work if the root is a composable but maybe you have some
AndroidViewBinding
in the middle? Does it work if the root is a XML layout but some children are composables? Do maybe only the composable parts of it get invalidated? Hmm not sure tbh
m

Michael Paus

08/26/2022, 3:09 PM
You might just give it a try and see what happens in your second scenario if you switch off the config changes in the manifest 😉.
s

Stylianos Gakis

08/26/2022, 3:14 PM
Yeah I haven’t tested such scenarios, I haven’t played with the idea yet that’s the thing, I’m just curious hence I’m starting this discussion. Is that the issue then? If there’s any of the interoperability APIs used it breaks the entire thing? Even if let’s say the View part is fine without reacting to the config changes?
a

Adam Powell

08/26/2022, 3:45 PM
It's situational for your app. The inflated viewbinding example is a good one; if you had different layout resources for different configurations, it wouldn't be automatically reinflated unless you specifically accounted for it in your own code
Or if your single layout xml referred to other resource constants that vary by configuration
a

Alex Vanyo

08/26/2022, 4:43 PM
Locale is also a good example where it’s easy to have subtle bugs when you’ve previously been operating in a world when activity recreation does the heavy lifting for you. If you call
Locale.getDefault()
(or a built-in method that uses it under the hood), then that use of the locale isn’t snapshot-state aware, so it won’t necessarily get updated. Or for a custom
View
, you’d need to listen to
View.onConfigurationChanged
to update yourself. With activity recreation, you could usually use
Locale.getDefault()
and be just fine because you’d end up calling it again as everything was reconstructed. Activity recreation is the original “reemit the UI when something changes”
s

Stylianos Gakis

08/26/2022, 5:02 PM
Aha that's also a concern. In a full compose app, which would recompose itself, it'd still be a problem right? If the component that happens to read the locale doesn't get recomposed that is. Because as I understand, the way compose handles these config changes itself is that they get updated and only if you're actually reading them somewhere things get recomposed. Like if the screen width changes everything will recompose, but if locale changes, there will be nothing recomposing if there's nothing reading the locale right? Trying to wrap my head around how all this works with compose and
configChanges
tbh still.
a

Adam Powell

08/26/2022, 5:08 PM
yes; specifically, if locale changes nothing will recompose if there's nothing reading the locale from a place that invalidates that locale read in a way that compose understands.
m

Michael Paus

08/26/2022, 5:27 PM
But if that is indeed the case then it means that Compose does not properly handle configuration changes at all. That comes a little bit as a surprise now after the statements made before.
a

Adam Powell

08/26/2022, 5:31 PM
Compose is not a sandbox that prevents you from escaping it. It properly handles config changes and gives you the tools to do the same in your own code
s

Stylianos Gakis

08/26/2022, 5:36 PM
Do you think it'd be possible to provide a little sample of how one would properly handle specifically locale changes in compose, at a place where you're using this locale? That'd clear a lot of misunderstandings I believe, and provide a nice reference for all future people who are gonna inevitably have the same questions regarding this.
a

Adam Powell

08/26/2022, 8:46 PM
Use
LocalConfiguration.current.locale
instead of
Locale.getDefault()
a

Alex Vanyo

08/26/2022, 9:38 PM
(
ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
is the compat one that won’t complain about being deprecated)
a

Adam Powell

08/26/2022, 9:39 PM
Or just suppress that particular deprecation globally because it's silly 🙃
z

Zoltan Demant

08/27/2022, 5:23 AM
Hmm, do I escape this hassle if I fetch strings in my app from one source? So I dont have any stringResource calls, etc. I do eventually call
context.getString
, but I control that context and its locale (upading to match the Android 13 changes)? Or are there any other cases where LocalConfiguration.current.locale is used besides for fetching strings?
m

Michael Paus

08/27/2022, 8:49 AM
Formatting numbers and parsing input comes to mind.
z

Zoltan Demant

08/27/2022, 11:11 AM
Exactly, but I don't think there's any composable (or component) that does that automatically for you?
m

Michael Paus

08/27/2022, 12:08 PM
Yes, but something needs to trigger a recomposition so that this can then be handled automatically by my own code. Android once decided that a change of the locale is worth a complete restart of the activity in a brute force manner. I expected Compose to do something similar, although somewhat less brutal, by automatically causing a complete recomposition of the currently visible screen.
94 Views