Skip to content

Commit

Permalink
[Crane] Use AnimatedContent to transition between content states. (#843)
Browse files Browse the repository at this point in the history
* [Crane] Use AnimatedContent to transition between content states.
  • Loading branch information
riggaroo committed Jun 20, 2022
1 parent df8e297 commit 203a582
Showing 1 changed file with 106 additions and 50 deletions.
156 changes: 106 additions & 50 deletions Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -85,7 +96,7 @@ fun CraneHome(
}
}

@OptIn(ExperimentalMaterialApi::class)
@OptIn(ExperimentalMaterialApi::class, ExperimentalAnimationApi::class)
@Composable
fun CraneHomeContent(
widthSize: WindowWidthSizeClass,
Expand Down Expand Up @@ -119,32 +130,55 @@ fun CraneHomeContent(
)
},
frontLayerContent = {
when (tabSelected) {
CraneScreen.Fly -> {
suggestedDestinations?.let { destinations ->
AnimatedContent(
targetState = tabSelected,
transitionSpec = {
val direction = if (initialState.ordinal < targetState.ordinal)
AnimatedContentScope.SlideDirection.Left else AnimatedContentScope
.SlideDirection.Right

slideIntoContainer(
towards = direction,
animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION)
) with
slideOutOfContainer(
towards = direction,
animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION)
) using SizeTransform(
clip = false,
sizeAnimationSpec = { _, _ ->
tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseInOut)
}
)
}
) { 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
)
}
}
}
Expand All @@ -159,7 +193,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(
Expand All @@ -171,6 +207,8 @@ private fun HomeTabBar(
}
}

private const val ANIMATED_CONTENT_ANIMATION_DURATION = 600
@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun SearchContent(
widthSize: WindowWidthSizeClass,
Expand All @@ -183,36 +221,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(
targetState = tabSelected,
transitionSpec = {
fadeIn(
animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseIn)
).with(
fadeOut(
animationSpec = tween(ANIMATED_CONTENT_ANIMATION_DURATION, easing = EaseOut)
)
).using(
SizeTransform(
sizeAnimationSpec = { _, _ ->
tween(ANIMATED_CONTENT_ANIMATION_DURATION, 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
)
)
}
}
}

Expand Down

0 comments on commit 203a582

Please sign in to comment.