From 37d81d653993955a1ccdbcc7615d911c3023ea54 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 13 Jun 2022 14:45:24 +0100 Subject: [PATCH 1/8] [Crane] Use AnimatedContent to transition between content states. --- .../samples/crane/base/ExploreSection.kt | 3 +- .../compose/samples/crane/home/CraneHome.kt | 146 ++++++++++++------ 2 files changed, 97 insertions(+), 52 deletions(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt index d579afa22..b3d6ff6fe 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt @@ -47,7 +47,6 @@ import androidx.compose.runtime.Composable import androidx.compose.samples.crane.R import androidx.compose.samples.crane.data.ExploreModel import androidx.compose.samples.crane.home.OnExploreItemClicked -import androidx.compose.samples.crane.ui.BottomSheetShape import androidx.compose.samples.crane.ui.crane_caption import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -68,7 +67,7 @@ fun ExploreSection( exploreList: List, onItemClicked: OnExploreItemClicked ) { - Surface(modifier = modifier.fillMaxSize(), color = Color.White, shape = BottomSheetShape) { + Surface(modifier = modifier.fillMaxSize(), color = Color.White) { Column(modifier = Modifier.padding(start = 24.dp, top = 20.dp, end = 24.dp)) { Text( text = title, diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index db50772b9..2a1b27536 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -16,6 +16,17 @@ package androidx.compose.samples.crane.home +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedContentScope +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.SizeTransform +import androidx.compose.animation.core.EaseIn +import androidx.compose.animation.core.EaseInOut +import androidx.compose.animation.core.EaseOut +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.with import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.layout.statusBarsPadding @@ -85,7 +96,7 @@ fun CraneHome( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalAnimationApi::class) @Composable fun CraneHomeContent( widthSize: WindowWidthSizeClass, @@ -119,32 +130,46 @@ fun CraneHomeContent( ) }, frontLayerContent = { - when (tabSelected) { - CraneScreen.Fly -> { - suggestedDestinations?.let { destinations -> + AnimatedContent( + tabSelected, + transitionSpec = { + val direction = if (initialState.ordinal < targetState.ordinal) + AnimatedContentScope.SlideDirection.Left else AnimatedContentScope + .SlideDirection.Right + slideIntoContainer(towards = direction, animationSpec = tween(600)) with + slideOutOfContainer( + towards = direction, + animationSpec = tween(600) + ) using SizeTransform(clip = false) + } + ) { targetState -> + when (targetState) { + CraneScreen.Fly -> { + suggestedDestinations?.let { destinations -> + ExploreSection( + widthSize = widthSize, + title = stringResource(R.string.explore_flights_by_destination), + exploreList = destinations, + onItemClicked = onExploreItemClicked + ) + } + } + CraneScreen.Sleep -> { ExploreSection( widthSize = widthSize, - title = stringResource(R.string.explore_flights_by_destination), - exploreList = destinations, + title = stringResource(R.string.explore_properties_by_destination), + exploreList = viewModel.hotels, + onItemClicked = onExploreItemClicked + ) + } + CraneScreen.Eat -> { + ExploreSection( + widthSize = widthSize, + title = stringResource(R.string.explore_restaurants_by_destination), + exploreList = viewModel.restaurants, onItemClicked = onExploreItemClicked ) } - } - CraneScreen.Sleep -> { - ExploreSection( - widthSize = widthSize, - title = stringResource(R.string.explore_properties_by_destination), - exploreList = viewModel.hotels, - onItemClicked = onExploreItemClicked - ) - } - CraneScreen.Eat -> { - ExploreSection( - widthSize = widthSize, - title = stringResource(R.string.explore_restaurants_by_destination), - exploreList = viewModel.restaurants, - onItemClicked = onExploreItemClicked - ) } } } @@ -159,7 +184,9 @@ private fun HomeTabBar( modifier: Modifier = Modifier ) { CraneTabBar( - modifier = modifier.wrapContentWidth().sizeIn(maxWidth = 500.dp), + modifier = modifier + .wrapContentWidth() + .sizeIn(maxWidth = 500.dp), onMenuClicked = openDrawer ) { tabBarModifier -> CraneTabs( @@ -171,6 +198,7 @@ private fun HomeTabBar( } } +@OptIn(ExperimentalAnimationApi::class) @Composable private fun SearchContent( widthSize: WindowWidthSizeClass, @@ -183,36 +211,54 @@ private fun SearchContent( // Reading datesSelected State from here instead of passing the String from the ViewModel // to cause a recomposition when the dates change. val selectedDates = viewModel.calendarState.calendarUiState.value.selectedDatesFormatted - - when (tabSelected) { - CraneScreen.Fly -> FlySearchContent( - widthSize = widthSize, - datesSelected = selectedDates, - searchUpdates = FlySearchContentUpdates( - onPeopleChanged = onPeopleChanged, - onToDestinationChanged = { viewModel.toDestinationChanged(it) }, - onDateSelectionClicked = onDateSelectionClicked, - onExploreItemClicked = onExploreItemClicked + AnimatedContent( + tabSelected, + transitionSpec = { + fadeIn( + animationSpec = tween(600, easing = EaseIn) + ).with( + fadeOut( + animationSpec = tween(600, easing = EaseOut) + ) + ).using( + SizeTransform( + sizeAnimationSpec = { _, _ -> + tween(1000, easing = EaseInOut) + } + ) ) - ) - CraneScreen.Sleep -> SleepSearchContent( - widthSize = widthSize, - datesSelected = selectedDates, - sleepUpdates = SleepSearchContentUpdates( - onPeopleChanged = onPeopleChanged, - onDateSelectionClicked = onDateSelectionClicked, - onExploreItemClicked = onExploreItemClicked + }, + ) { targetState -> + when (targetState) { + CraneScreen.Fly -> FlySearchContent( + widthSize = widthSize, + datesSelected = selectedDates, + searchUpdates = FlySearchContentUpdates( + onPeopleChanged = onPeopleChanged, + onToDestinationChanged = { viewModel.toDestinationChanged(it) }, + onDateSelectionClicked = onDateSelectionClicked, + onExploreItemClicked = onExploreItemClicked + ) ) - ) - CraneScreen.Eat -> EatSearchContent( - widthSize = widthSize, - datesSelected = selectedDates, - eatUpdates = EatSearchContentUpdates( - onPeopleChanged = onPeopleChanged, - onDateSelectionClicked = onDateSelectionClicked, - onExploreItemClicked = onExploreItemClicked + CraneScreen.Sleep -> SleepSearchContent( + widthSize = widthSize, + datesSelected = selectedDates, + sleepUpdates = SleepSearchContentUpdates( + onPeopleChanged = onPeopleChanged, + onDateSelectionClicked = onDateSelectionClicked, + onExploreItemClicked = onExploreItemClicked + ) ) - ) + CraneScreen.Eat -> EatSearchContent( + widthSize = widthSize, + datesSelected = selectedDates, + eatUpdates = EatSearchContentUpdates( + onPeopleChanged = onPeopleChanged, + onDateSelectionClicked = onDateSelectionClicked, + onExploreItemClicked = onExploreItemClicked + ) + ) + } } } From c65af5cbcc353cd4f90805a32109e2cd5dc450f7 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 13 Jun 2022 16:09:44 +0100 Subject: [PATCH 2/8] [Crane] Use AnimatedContent to transition between content states. --- .../java/androidx/compose/samples/crane/base/ExploreSection.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt index b3d6ff6fe..d579afa22 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt @@ -47,6 +47,7 @@ import androidx.compose.runtime.Composable import androidx.compose.samples.crane.R import androidx.compose.samples.crane.data.ExploreModel import androidx.compose.samples.crane.home.OnExploreItemClicked +import androidx.compose.samples.crane.ui.BottomSheetShape import androidx.compose.samples.crane.ui.crane_caption import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -67,7 +68,7 @@ fun ExploreSection( exploreList: List, onItemClicked: OnExploreItemClicked ) { - Surface(modifier = modifier.fillMaxSize(), color = Color.White) { + Surface(modifier = modifier.fillMaxSize(), color = Color.White, shape = BottomSheetShape) { Column(modifier = Modifier.padding(start = 24.dp, top = 20.dp, end = 24.dp)) { Text( text = title, From 3f140dbd13d3289df48efc1b7fcd8ea256ffe11a Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Wed, 15 Jun 2022 08:53:46 +0100 Subject: [PATCH 3/8] [Crane] Use AnimatedContent to transition between content states. --- .../java/androidx/compose/samples/crane/home/CraneHome.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index 2a1b27536..c19757dbf 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -136,7 +136,9 @@ fun CraneHomeContent( val direction = if (initialState.ordinal < targetState.ordinal) AnimatedContentScope.SlideDirection.Left else AnimatedContentScope .SlideDirection.Right - slideIntoContainer(towards = direction, animationSpec = tween(600)) with + + slideIntoContainer(towards = direction, + animationSpec = tween(600)) with slideOutOfContainer( towards = direction, animationSpec = tween(600) From a270402aa541090820e45f587742630aa5d434b8 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Wed, 15 Jun 2022 10:39:58 +0100 Subject: [PATCH 4/8] [Crane] Use AnimatedContent to transition between content states. --- .../androidx/compose/samples/crane/home/CraneHome.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index c19757dbf..51ccca7cf 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -137,12 +137,16 @@ fun CraneHomeContent( AnimatedContentScope.SlideDirection.Left else AnimatedContentScope .SlideDirection.Right - slideIntoContainer(towards = direction, - animationSpec = tween(600)) with + slideIntoContainer( + towards = direction, + animationSpec = tween(600) + ) with slideOutOfContainer( towards = direction, animationSpec = tween(600) - ) using SizeTransform(clip = false) + ) using SizeTransform(clip = false, sizeAnimationSpec = { initialSize, targetSize -> + tween(600, easing = EaseInOut) + }) } ) { targetState -> when (targetState) { From 294924230d3f64bf4e113874b42d9b8d528c5965 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 20 Jun 2022 14:28:25 +0100 Subject: [PATCH 5/8] [Crane] PR Feedback --- .../compose/samples/crane/home/CraneHome.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index 51ccca7cf..35791f3b6 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -131,7 +131,7 @@ fun CraneHomeContent( }, frontLayerContent = { AnimatedContent( - tabSelected, + targetState = tabSelected, transitionSpec = { val direction = if (initialState.ordinal < targetState.ordinal) AnimatedContentScope.SlideDirection.Left else AnimatedContentScope @@ -141,12 +141,14 @@ fun CraneHomeContent( towards = direction, animationSpec = tween(600) ) with - slideOutOfContainer( - towards = direction, - animationSpec = tween(600) - ) using SizeTransform(clip = false, sizeAnimationSpec = { initialSize, targetSize -> - tween(600, easing = EaseInOut) - }) + slideOutOfContainer( + towards = direction, + animationSpec = tween(600) + ) using SizeTransform( + clip = false, + sizeAnimationSpec = { initialSize, targetSize -> + tween(600, easing = EaseInOut) + }) } ) { targetState -> when (targetState) { From 99eefd0e42726f5d7042e594ae8602ee56ebf2b5 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 20 Jun 2022 14:28:55 +0100 Subject: [PATCH 6/8] [Crane] PR Feedback --- .../main/java/androidx/compose/samples/crane/home/CraneHome.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index 35791f3b6..94446af97 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -220,7 +220,7 @@ private fun SearchContent( // to cause a recomposition when the dates change. val selectedDates = viewModel.calendarState.calendarUiState.value.selectedDatesFormatted AnimatedContent( - tabSelected, + targetState = tabSelected, transitionSpec = { fadeIn( animationSpec = tween(600, easing = EaseIn) From 9212562ebdaa145e73e76ace237761ed87657036 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 20 Jun 2022 14:31:36 +0100 Subject: [PATCH 7/8] [Crane] PR Feedback --- .../compose/samples/crane/home/CraneHome.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index 94446af97..aa45935b0 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -139,15 +139,15 @@ fun CraneHomeContent( slideIntoContainer( towards = direction, - animationSpec = tween(600) + animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION) ) with slideOutOfContainer( towards = direction, - animationSpec = tween(600) + animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION) ) using SizeTransform( clip = false, - sizeAnimationSpec = { initialSize, targetSize -> - tween(600, easing = EaseInOut) + sizeAnimationSpec = { _, _ -> + tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseInOut) }) } ) { targetState -> @@ -206,6 +206,7 @@ private fun HomeTabBar( } } +private const val ANIMATED_CONTENT_ANIMATION_DURATION = 600 @OptIn(ExperimentalAnimationApi::class) @Composable private fun SearchContent( @@ -223,15 +224,15 @@ private fun SearchContent( targetState = tabSelected, transitionSpec = { fadeIn( - animationSpec = tween(600, easing = EaseIn) + animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseIn) ).with( fadeOut( - animationSpec = tween(600, easing = EaseOut) + animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseOut) ) ).using( SizeTransform( sizeAnimationSpec = { _, _ -> - tween(1000, easing = EaseInOut) + tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseInOut) } ) ) From 8300f0f797c9cccae737abc318ee8ddecbb64c54 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 20 Jun 2022 14:34:17 +0100 Subject: [PATCH 8/8] [Crane] PR Feedback --- .../androidx/compose/samples/crane/home/CraneHome.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index aa45935b0..1bc421e52 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -141,14 +141,15 @@ fun CraneHomeContent( towards = direction, animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION) ) with - slideOutOfContainer( - towards = direction, - animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION) - ) using SizeTransform( + slideOutOfContainer( + towards = direction, + animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION) + ) using SizeTransform( clip = false, sizeAnimationSpec = { _, _ -> tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseInOut) - }) + } + ) } ) { targetState -> when (targetState) {