Alex Vanyo's Avatar

Alex Vanyo

@vanyo.dev.bsky.social

Android Software Engineer Helping build adaptive Compose everywhere!

545 Followers  |  100 Following  |  105 Posts  |  Joined: 02.11.2024  |  1.6163

Latest posts by vanyo.dev on Bluesky

The recording from my talk on how to handle configuration changes in Compose at #dcnyc25 is out!

Hopefully this helps explain what android:configChanges is responsible for in #AndroidDev and why it's important to know what promises you make when setting it.

www.youtube.com/watch?v=K5-9...

30.07.2025 04:16 โ€” ๐Ÿ‘ 18    ๐Ÿ” 4    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

I'm curious how prevalent the onGloballyPositioned pattern is and why - does it feel like the best way to accomplish more custom layout behavior? Is it the easiest thing to get something working close enough? Are there missing tools that would make it less likely you'd use onGloballyPositioned?

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0

This video from last year goes into a lot more detail about the problem space here, along with some examples of how to approach different problems:
www.youtube.com/watch?v=PUxt...

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Unfortunately there's not really a one-size-fits-all solution for every case, but don't be afraid of a custom layout - if you're already doing some math to change the layout of something based on something else, you're about 80% of the way there to writing a custom layout.

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

This can also wreck havoc on animations - maybe they can cover up some of the jankiness, but animations need to have a consistent view of the layout as it animates at each point in time. Shared element transitions don't really work if the shared element disappears completely for a frame.

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Nesting this approach makes the situation even worse - each time you put a calculation like this inside another one, it adds an additional frame required to resolve the whole layout.

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

When you have composition being driven by information that you can only get in a later phase, like measurement, layout or drawing, the first composition can't be correct!

This means that the first frame might be blank, or components might jump around as you get more info.

15.07.2025 23:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

A response to the section on "How Can I Determine the Size and Position of Descendants of Peers?"

Using onGloballyPositioned (or onSizeChanged, or similar modifiers) like this is a quick way to get yourself into trouble with layouts that take multiple frames to resolve that can flash or look janky.

15.07.2025 23:20 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I smile every time I hear a voice assistant says "Panic! at the Disco" out loud when playing music, it dutifully pronounces the punctuation.

15.07.2025 16:52 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Video thumbnail

Did you know... Android Studio has introduced resizable previews for Compose previews? Allowing you to test your layouts across the spectrum of device sizes easily inside Android Studio. ๐Ÿ’ป

developer.android.com/studio/previ...

07.07.2025 09:59 โ€” ๐Ÿ‘ 51    ๐Ÿ” 9    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 1

I really like "artisanal" as a descriptor, I think it's going to matter even more to be specific about expectations for types of code based on what it's for.

Would anyone really need an artisanal repro sample, or an artisanal one-time use script?

What about an artisanal library or sample?

03.07.2025 22:26 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

And to reiterate again: configuration changes will happen, and you have to react to them. For each type of configuration change, your options are:
- using Activity recreation, and properly preserving state through it
- opting-out of recreation, and updating everything in place

01.07.2025 22:21 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Some are a lot trickier to handle directly - and it's pretty easy to write code that works assuming that recreation happens.

Opting out of recreation is also a promise that new code works properly with updating in-place when the configuration changes.

01.07.2025 22:21 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

It's also not all or nothing! Most Android apps can probably opt-out of recreation for some configuration changes that don't need apps to do much (if anything), like keyboard, touchscreen, and colorMode.

That'd immediately solve a whole class of bugs for physical keyboards and connected displays.

01.07.2025 22:21 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

TL;DR: if you know the promise you are making, you can opt-out of Activity recreation via android:configChanges.

The golden rule to do so properly in Compose is to have everything using configuration depend on a snapshot-state-backed source for it, like LocalConfiguration and LocalResources.

01.07.2025 22:21 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

...and the source for my slides is here!
github.com/alexvanyo/al...

I built my talk with Compose itself, using @bnorm.dev's github.com/bnorm/storyb... project. Shared elements and transitions galore, directly using the Compose APIs for it.

01.07.2025 22:21 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

It was great to see both familiar faces and new ones at #dcnyc25 last week - especially to see how everyone's figuring out what #AndroidDev will look like with the new tools are moving at a blistering speed.

The slides for my talk are available here: alex.vanyo.dev/talks/configurationchanges

01.07.2025 22:21 โ€” ๐Ÿ‘ 12    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 1

I'm excited to be speaking at #DroidconNYC next Thursday, hope to see you there!

I'll be covering how to handle configuration changes in Compose, and specifically trying to answer the question of what you should put in android:configChanges and - probably more importantly - why.

#AndroidDev

20.06.2025 22:45 โ€” ๐Ÿ‘ 25    ๐Ÿ” 5    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Are you using the platform level drag and drop here, or something app-local?

20.06.2025 16:54 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Also - depending on jurisdiction, supporting multiple orientations can be an accessibility requirement, regardless of device type.

08.06.2025 12:46 โ€” ๐Ÿ‘ 4    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Prioritize accordingly based on what makes sense for your app and use cases - but users are absolutely using it across different form factors, window sizes and input types.

08.06.2025 12:46 โ€” ๐Ÿ‘ 3    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Is that as many as just phones? No.

Is that a lot of people who want a better experience than an app breaking or having an unusable layout on their primary or secondary devices? Yes.

08.06.2025 12:46 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

What number would stop being "nobody"? Combined across foldables, tablets, ChromeOS, and cars there are over 500 million active devices now where users expect apps that aren't just portrait phone apps - and that leaves out the additional devices capable of connecting external displays.

08.06.2025 12:46 โ€” ๐Ÿ‘ 4    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I assume iOS is going to have all the same accessibility requirements for orientation though, right? Is it even less common on iOS to support both orientations than Android right now?

29.05.2025 16:48 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

What do you think worries the product manager the most about it?

Is it tech debt for handling configuration changes themselves, or is it other things related to resizing and orientation changes? Does directing product managers to the resources we have around the Android 16 changes help?

29.05.2025 15:24 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Thinking about configuration changes isn't optional.

Imagine a website trying to prevent the browser window from being resized or breaking when it does. Android apps can't disable configuration changes and need to react to them correctly without losing state using the tools available.

29.05.2025 02:42 โ€” ๐Ÿ‘ 20    ๐Ÿ” 3    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 1

โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โŒโœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โŒโœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โŒโœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โŒโœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โŒโœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…โœ…

22.05.2025 18:52 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Ooh, this is interesting - it looks like the two coordinate spaces defined right now are for the bounds of the position of the Modifier and another for the underlying image?

22.05.2025 18:47 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

How many โœ…s are we talking about?

22.05.2025 18:13 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I can now respond with what I wanted to say here without spoiling the I/O launch - I think it'd be amazing to see what shared-between-scenes elements looks like - so not root level, and not within a pane, but somewhere in-between

22.05.2025 17:13 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

@vanyo.dev is following 20 prominent accounts