1

I'm using SharedTransitionLayout in Jetpack Compose to animate elements across different screens. The issue occurs when I use Modifier.sharedBounds inside the title section of CenterAlignedTopAppBar.

βœ… If I place the sharedBounds modifier outside the title, everything works fine. ❌ But when I use it inside title, the app crashes on launch with this error:

java.lang.IllegalStateException: Uninitialized LayoutCoordinates. Please make sure when using the SharedTransitionScope composable function, the modifier passed to the child content is being used, or use SharedTransitionLayout instead.

What I've observed so far:

If I remove sharedBounds, the crash disappears.

All transition-related objects (sharedTransitionScope, animatedVisibilityScope, sharedContentState) are properly initialized.

The crash only happens on the first screen that loads.

If I navigate to another screen where sharedBounds is inside TopAppBar, it works perfectly fine (as long as it's not the first screen).

Any screen that is set as the first screen crashes if it contains this AppBar setup.

Here’s a simplified version of the code that causes the issue:

Scaffold(
 topBar = {
 CenterAlignedTopAppBar(
 title = {
 with(sharedTransitionScope) {
 Text(
 modifier = Modifier.sharedBounds(
 sharedContentState = rememberSharedContentState(
 key = "TITLE_TRANSITION_KEY"
 ),
 animatedVisibilityScope = animatedVisibilityScope
 ),
 text = "My App",
 fontWeight = FontWeight.Bold,
 textAlign = TextAlign.Center
 )
 }
 }
 )
 }
) { / Content / }

Temporary workaround that works:

If I check isReady before applying sharedBounds, the crash is avoided:

if (isReady) {
 Modifier.sharedBounds(...)
}

But I would like to understand why this happens and how to properly fix it.

My question:

Why does sharedBounds inside TopAppBar only crash when it's used in the first screen, but not in subsequent screens?

Is there a proper way to ensure that sharedBounds is initialized correctly when the first screen loads?

Could this be a bug in SharedTransitionLayout, or am I missing something in my setup?


AbstractActivity.kt

abstract class AbstractActivity : ComponentActivity() {
 @Inject
 lateinit var preferences: PreferencesUseCase
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 val themeId = preferences.getInt(
 CommonConstants.PREFERENCE_THEME_ID_KEY, CommonConstants.THEME_DARK_KEY
 )
 val appTheme = ThemeHelper.getTheme(themeId, ThemeHelper.DEFAULT_THEME)
 setTheme(appTheme.resourceId)
 enableEdgeToEdge()
 setContent {
 ApplicationTheme(appTheme, direction = LayoutDirection.Rtl) {
 AppContent()
 }
 }
 }
 @Composable
 abstract fun AppContent()
}

AppActivity.kt

@AndroidEntryPoint
class AppActivity : AbstractActivity() {
 @Composable
 override fun AppContent() {
 val navController = rememberNavController()
 SharedTransitionLayout {
 NavHost(
 navController = navController,
 modifier = Modifier
 .fillMaxSize()
 .imePadding()
 ,
 startDestination = AppDestinations.Main
 ) {
 composable<AppDestinations.Main> {
 MainScreen(
 sharedTransitionScope = this@SharedTransitionLayout,
 animatedVisibilityScope = this
 )
 }
 composable<AppDestinations.Settings> {
 SettingsScreen(
 sharedTransitionScope = this@SharedTransitionLayout,
 animatedVisibilityScope = this
 )
 }
 }
 }
 }
}

MainScreen.kt

@Composable
fun MainScreen(
 sharedTransitionScope: SharedTransitionScope,
 animatedVisibilityScope: AnimatedVisibilityScope
) {
 Scaffold(
 topBar = {
 with(sharedTransitionScope) {
 CenterAlignedTopAppBar(
 title = {
 Text(
 modifier = Modifier
 .sharedBounds(
 sharedContentState = rememberSharedContentState(
 key = "TOOLBAR_TITLE_EXPLODE_BOUNDS"
 ),
 animatedVisibilityScope = animatedVisibilityScope
 )
 ,
 text = stringResource(R.string.app_name),
 fontWeight = FontWeight.Bold,
 textAlign = TextAlign.Center,,
 )
 }
 )
 }
 }
 
 ) { innerPadding ->
 ...
 }
}

SettingsScreen.kt

@Composable
fun SettingsScreen(
 sharedTransitionScope: SharedTransitionScope,
 animatedVisibilityScope: AnimatedVisibilityScope,
) {
 Scaffold(
 topBar = {
 with(sharedTransitionScope) {
 TopAppBar(
 title = {
 Text(
 modifier = Modifier
 .sharedBounds(
 sharedContentState = rememberSharedContentState(
 key = "TOOLBAR_TITLE_EXPLODE_BOUNDS"
 ),
 animatedVisibilityScope = animatedVisibilityScope
 )
 ,
 text = stringResource(R.string.toolbar_title_settings),
 fontWeight = FontWeight.Bold,
 textAlign = TextAlign.Center
 )
 }
 )
 }
 }
 ) { innerPadding ->
 ...
 }
}

Thanks in advance for any insights! I really appreciate any help in understanding why this happens and how to properly fix it. If you need more details, feel free to ask, and I'll be happy to provide additional information. πŸš€

asked Feb 25, 2025 at 14:58

1 Answer 1

1

The root cause of your problem appears to be related to the initialization timing of the LayoutCoordinates when using SharedTransitionLayout.When your app first launches and displays the initial screen (MainScreen), the TopAppBar's title composable is being measured and laid out before the LayoutCoordinates are fully initialized, causing the "Uninitialized LayoutCoordinates" error. This only happens on the first screen because subsequent screens benefit from already initialized layout coordinates.

Use LaunchedEffect with a delay

@Composable
fun MainScreen(
sharedTransitionScope: SharedTransitionScope,
animatedVisibilityScope: AnimatedVisibilityScope
) {
var isReady by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
 // Small delay to ensure layout coordinates are initialized
 delay(100)
 isReady = true
}
Scaffold(
 topBar = {
 with(sharedTransitionScope) {
 CenterAlignedTopAppBar(
 title = {
 Text(
 modifier = if (isReady) {
 Modifier.sharedBounds(
 sharedContentState = rememberSharedContentState(
 key = "TOOLBAR_TITLE_EXPLODE_BOUNDS"
 ),
 animatedVisibilityScope = animatedVisibilityScope
 )
 } else Modifier,
 text = stringResource(R.string.app_name),
 fontWeight = FontWeight.Bold,
 textAlign = TextAlign.Center,
 )
 }
 )
 }
 }
) { innerPadding ->
 // Content
}
}
answered Feb 26, 2025 at 7:21
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.