From ed4a4436b86a0a77c6ce69bf23fc7f6b50f2e7ae Mon Sep 17 00:00:00 2001 From: OneWay Date: Fri, 25 Sep 2026 23:53:10 +0800 Subject: [PATCH] fix(navigation): keep Home composed while article is open Article was an AnimatedContent target: opening it disposed Home, and returning from it recreated the whole results list in a single frame. The article screen now renders as a full-screen AnimatedVisibility overlay above Home, which stays composed for the whole article session. --- .../research/ui/navigation/AppNavigation.kt | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt b/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt index 8015a52..69460a8 100644 --- a/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt +++ b/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt @@ -2,16 +2,22 @@ package com.example.research.ui.navigation import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.togetherWith import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2 import androidx.compose.runtime.* import androidx.compose.runtime.saveable.* +import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND import com.example.research.feature.search.SearchAction @@ -101,10 +107,11 @@ fun AppNavigation( val effectiveScreen = when { currentScreen == Screen.About -> Screen.About - currentScreen == Screen.Article && articleState == null -> if (shouldShowSettings) Screen.Settings else Screen.Home shouldShowSettings -> Screen.Settings - else -> currentScreen + currentScreen == Screen.Settings -> Screen.Settings + else -> Screen.Home } + Box { AnimatedContent( targetState = effectiveScreen, transitionSpec = { @@ -150,7 +157,27 @@ fun AppNavigation( onNavigateToAbout = { screenStack.add(Screen.About) } ) } - Screen.Article -> { + Screen.About -> { + AboutScreen( + onNavigateBack = { + if (screenStack.size > 1) screenStack.removeAt(screenStack.lastIndex) + } + ) + } + Screen.Article -> {} + } + } + + AnimatedVisibility( + visible = currentScreen == Screen.Article && articleState != null, + enter = fadeIn(tween(180)) + slideInHorizontally(tween(180)) { it / 3 }, + exit = fadeOut(tween(180)) + slideOutHorizontally(tween(180)) { it / 3 }, + label = "articleOverlay", + ) { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.surface + ) { ArticleRoute( searchViewModel = searchViewModel, onNavigateBack = { @@ -162,13 +189,6 @@ fun AppNavigation( } ) } - Screen.About -> { - AboutScreen( - onNavigateBack = { - if (screenStack.size > 1) screenStack.removeAt(screenStack.lastIndex) - } - ) - } - } + } } }