Skip to content

Commit 8b93df8

Browse files
Multiple shared transition element Improvements
1 parent 5989683 commit 8b93df8

File tree

5 files changed

+65
-5
lines changed

5 files changed

+65
-5
lines changed

app/src/main/kotlin/com/mr3y/podcaster/ui/screens/DownloadsScreen.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@ import com.mr3y.podcaster.core.sampledata.EpisodesWithDownloadMetadata
4747
import com.mr3y.podcaster.ui.components.AnimatedAsyncImage
4848
import com.mr3y.podcaster.ui.components.DownloadButton
4949
import com.mr3y.podcaster.ui.components.LoadingIndicator
50+
import com.mr3y.podcaster.ui.components.LocalAnimatedVisibilityScope
51+
import com.mr3y.podcaster.ui.components.LocalSharedTransitionScope
5052
import com.mr3y.podcaster.ui.components.TopBar
53+
import com.mr3y.podcaster.ui.components.animateEnterExit
5154
import com.mr3y.podcaster.ui.components.rememberHtmlToAnnotatedString
55+
import com.mr3y.podcaster.ui.components.renderInSharedTransitionScopeOverlay
5256
import com.mr3y.podcaster.ui.presenter.PodcasterAppState
5357
import com.mr3y.podcaster.ui.presenter.downloads.DownloadsUIState
5458
import com.mr3y.podcaster.ui.presenter.downloads.DownloadsViewModel
@@ -106,6 +110,11 @@ fun DownloadsScreen(
106110
scrolledContainerColor = Color.Transparent,
107111
),
108112
modifier = Modifier
113+
.renderInSharedTransitionScopeOverlay(
114+
LocalSharedTransitionScope.current,
115+
zIndexInOverlay = 1f
116+
)
117+
.animateEnterExit(LocalAnimatedVisibilityScope.current)
109118
.fillMaxWidth()
110119
.padding(vertical = 8.dp)
111120
.padding(end = 16.dp),

app/src/main/kotlin/com/mr3y/podcaster/ui/screens/EpisodeDetailsScreen.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ import com.mr3y.podcaster.ui.components.PlayPauseCompactButton
6060
import com.mr3y.podcaster.ui.components.PullToRefresh
6161
import com.mr3y.podcaster.ui.components.RemoveFromQueueButton
6262
import com.mr3y.podcaster.ui.components.TopBar
63+
import com.mr3y.podcaster.ui.components.animateEnterExit
6364
import com.mr3y.podcaster.ui.components.rememberHtmlToAnnotatedString
6465
import com.mr3y.podcaster.ui.components.rememberSharedContentState
66+
import com.mr3y.podcaster.ui.components.renderInSharedTransitionScopeOverlay
6567
import com.mr3y.podcaster.ui.components.sharedBounds
6668
import com.mr3y.podcaster.ui.components.sharedElement
6769
import com.mr3y.podcaster.ui.presenter.PodcasterAppState
@@ -180,7 +182,13 @@ fun EpisodeDetailsScreen(
180182
containerColor = MaterialTheme.colorScheme.surface,
181183
navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
182184
),
183-
modifier = Modifier.fillMaxWidth(),
185+
modifier = Modifier
186+
.renderInSharedTransitionScopeOverlay(
187+
LocalSharedTransitionScope.current,
188+
zIndexInOverlay = 1f
189+
)
190+
.animateEnterExit(LocalAnimatedVisibilityScope.current)
191+
.fillMaxWidth(),
184192
)
185193
},
186194
snackbarHost = { SnackbarHost(snackBarHostState, Modifier.padding(externalContentPadding)) },

app/src/main/kotlin/com/mr3y/podcaster/ui/screens/PodcastDetailsScreen.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,15 @@ import com.mr3y.podcaster.ui.components.AddToQueueButton
8989
import com.mr3y.podcaster.ui.components.AnimatedAsyncImage
9090
import com.mr3y.podcaster.ui.components.Error
9191
import com.mr3y.podcaster.ui.components.LoadingIndicator
92+
import com.mr3y.podcaster.ui.components.LocalAnimatedVisibilityScope
93+
import com.mr3y.podcaster.ui.components.LocalSharedTransitionScope
9294
import com.mr3y.podcaster.ui.components.PlayPauseCompactButton
9395
import com.mr3y.podcaster.ui.components.PullToRefresh
9496
import com.mr3y.podcaster.ui.components.RemoveFromQueueButton
9597
import com.mr3y.podcaster.ui.components.TopBar
98+
import com.mr3y.podcaster.ui.components.animateEnterExit
9699
import com.mr3y.podcaster.ui.components.rememberHtmlToAnnotatedString
100+
import com.mr3y.podcaster.ui.components.renderInSharedTransitionScopeOverlay
97101
import com.mr3y.podcaster.ui.presenter.PodcasterAppState
98102
import com.mr3y.podcaster.ui.presenter.RefreshResult
99103
import com.mr3y.podcaster.ui.presenter.podcastdetails.PodcastDetailsUIEvent
@@ -240,7 +244,13 @@ fun PodcastDetailsScreen(
240244
dominantColorState.onColor
241245
},
242246
),
243-
modifier = Modifier.fillMaxWidth(),
247+
modifier = Modifier
248+
.renderInSharedTransitionScopeOverlay(
249+
LocalSharedTransitionScope.current,
250+
zIndexInOverlay = 1f
251+
)
252+
.animateEnterExit(LocalAnimatedVisibilityScope.current)
253+
.fillMaxWidth(),
244254
)
245255
},
246256
containerColor = MaterialTheme.colorScheme.surface,

ui/design-system/src/main/kotlin/com/mr3y/podcaster/ui/components/Image.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ fun AnimatedAsyncImage(
2727
.memoryCacheKey(sharedTransitionKey)
2828
.build(),
2929
contentDescription = contentDescription,
30-
modifier = Modifier
30+
modifier = modifier
3131
.sharedElement(
3232
LocalSharedTransitionScope.current,
3333
LocalAnimatedVisibilityScope.current,
3434
rememberSharedContentState(key = sharedTransitionKey),
35-
)
36-
.then(modifier),
35+
),
3736
contentScale = contentScale,
3837
onState = onState,
3938
)

ui/design-system/src/main/kotlin/com/mr3y/podcaster/ui/components/SharedElementTransition.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import androidx.compose.animation.core.VisibilityThreshold
1616
import androidx.compose.animation.core.spring
1717
import androidx.compose.animation.fadeIn
1818
import androidx.compose.animation.fadeOut
19+
import androidx.compose.animation.slideInVertically
20+
import androidx.compose.animation.slideOutVertically
1921
import androidx.compose.runtime.Composable
2022
import androidx.compose.runtime.staticCompositionLocalOf
2123
import androidx.compose.ui.Alignment.Companion.Center
@@ -105,6 +107,38 @@ fun Modifier.sharedBounds(
105107
}
106108
}
107109

110+
fun Modifier.renderInSharedTransitionScopeOverlay(
111+
sharedTransitionScope: SharedTransitionScope?,
112+
zIndexInOverlay: Float = 0f,
113+
clipInOverlayDuringTransition: (LayoutDirection, Density) -> Path? = { _, _ -> null }
114+
): Modifier {
115+
return if (sharedTransitionScope == null) {
116+
this
117+
} else {
118+
with(sharedTransitionScope) {
119+
renderInSharedTransitionScopeOverlay(
120+
zIndexInOverlay = zIndexInOverlay,
121+
clipInOverlayDuringTransition = clipInOverlayDuringTransition
122+
)
123+
}
124+
}
125+
}
126+
127+
fun Modifier.animateEnterExit(
128+
animatedVisibilityScope: AnimatedVisibilityScope?
129+
): Modifier {
130+
return if (animatedVisibilityScope == null) {
131+
this
132+
} else {
133+
with(animatedVisibilityScope) {
134+
animateEnterExit(
135+
enter = fadeIn() + slideInVertically { -it },
136+
exit = fadeOut() + slideOutVertically { -it },
137+
)
138+
}
139+
}
140+
}
141+
108142
fun Modifier.skipToLookaheadSize(
109143
sharedTransitionScope: SharedTransitionScope?,
110144
): Modifier {

0 commit comments

Comments
 (0)