@@ -68,6 +68,7 @@ import androidx.compose.runtime.CompositionLocalProvider
6868import androidx.compose.runtime.setValue
6969import androidx.compose.ui.Alignment
7070import androidx.compose.ui.Modifier
71+ import androidx.compose.ui.draw.clipToBounds
7172import androidx.compose.ui.graphics.graphicsLayer
7273import androidx.compose.ui.layout.onSizeChanged
7374import androidx.compose.ui.platform.LocalDensity
@@ -634,6 +635,50 @@ class MainActivity : ComponentActivity() {
634635 } else {
635636 0 .dp
636637 }
638+ val animatedBottomBarPadding by animateDpAsState(
639+ targetValue = if (navBarStyle == NavBarStyle .FULL_WIDTH ) 0 .dp else systemNavBarInset,
640+ animationSpec = tween(400 ),
641+ label = " BottomBarPadding"
642+ )
643+ val bottomBarPadding = animatedBottomBarPadding
644+ val navBarHeight = if (navBarStyle == NavBarStyle .DEFAULT ) {
645+ NavBarContentHeight
646+ } else {
647+ NavBarContentHeightFullWidth + systemNavBarInset
648+ }
649+ val navBarOccupiedHeight by remember(navBarHeight, bottomBarPadding) {
650+ derivedStateOf { navBarHeight + bottomBarPadding }
651+ }
652+ val navBarVisibilityProgress by animateFloatAsState(
653+ targetValue = if (shouldHideNavigationBar) 0f else 1f ,
654+ animationSpec = tween(
655+ durationMillis = 220 ,
656+ easing = LinearOutSlowInEasing
657+ ),
658+ label = " NavBarVisibilityProgress"
659+ )
660+ val visibleNavBarOccupiedHeight by remember(navBarOccupiedHeight, navBarVisibilityProgress) {
661+ derivedStateOf { navBarOccupiedHeight * navBarVisibilityProgress }
662+ }
663+ val miniPlayerBottomMargin by remember(systemNavBarInset, visibleNavBarOccupiedHeight) {
664+ derivedStateOf {
665+ if (visibleNavBarOccupiedHeight > systemNavBarInset) {
666+ visibleNavBarOccupiedHeight
667+ } else {
668+ systemNavBarInset
669+ }
670+ }
671+ }
672+ val shouldRenderNavigationBar by remember(shouldHideNavigationBar, navBarVisibilityProgress) {
673+ derivedStateOf {
674+ ! shouldHideNavigationBar || navBarVisibilityProgress > 0.01f
675+ }
676+ }
677+ val isNavBarEffectivelyHidden by remember(shouldHideNavigationBar, navBarVisibilityProgress) {
678+ derivedStateOf {
679+ shouldHideNavigationBar && navBarVisibilityProgress <= 0.01f
680+ }
681+ }
637682
638683 val drawerState = rememberDrawerState(initialValue = DrawerValue .Closed )
639684 val scope = rememberCoroutineScope()
@@ -689,7 +734,7 @@ class MainActivity : ComponentActivity() {
689734 Scaffold (
690735 modifier = Modifier .fillMaxSize(),
691736 bottomBar = {
692- if (! shouldHideNavigationBar ) {
737+ if (shouldRenderNavigationBar ) {
693738 val playerContentExpansionFraction = playerViewModel.playerContentExpansionFraction.value
694739 val currentSongId by remember {
695740 playerViewModel.stablePlayerState
@@ -753,13 +798,6 @@ class MainActivity : ComponentActivity() {
753798 )
754799 }
755800
756- val animatedBottomBarPadding by animateDpAsState(
757- targetValue = if (navBarStyle == NavBarStyle .FULL_WIDTH ) 0 .dp else systemNavBarInset,
758- animationSpec = tween(400 ),
759- label = " BottomBarPadding"
760- )
761- val bottomBarPadding = animatedBottomBarPadding
762-
763801 var componentHeightPx by remember { mutableStateOf(0 ) }
764802 val density = LocalDensity .current
765803 val shadowOverflowPx = remember(navBarElevation, density) {
@@ -782,26 +820,24 @@ class MainActivity : ComponentActivity() {
782820 Box (
783821 modifier = Modifier
784822 .fillMaxWidth()
785- .padding(bottom = bottomBarPadding)
786- .onSizeChanged { componentHeightPx = it.height }
787- .graphicsLayer {
788- translationY = animatedTranslationY
789- alpha = 1f
790- }
823+ .height(visibleNavBarOccupiedHeight)
824+ .clipToBounds()
791825 ) {
792- val navHeight: Dp = if (navBarStyle == NavBarStyle .DEFAULT ) {
793- NavBarContentHeight
794- } else {
795- NavBarContentHeightFullWidth + systemNavBarInset
796- }
797826 val onSearchIconDoubleTap = remember(playerViewModel) {
798827 { playerViewModel.onSearchNavIconDoubleTapped() }
799828 }
800829
801830 Surface (
802831 modifier = Modifier
832+ .align(Alignment .BottomCenter )
803833 .fillMaxWidth()
804- .height(navHeight)
834+ .padding(bottom = bottomBarPadding)
835+ .onSizeChanged { componentHeightPx = it.height }
836+ .graphicsLayer {
837+ translationY = animatedTranslationY
838+ alpha = 1f
839+ }
840+ .height(navBarHeight)
805841 .padding(horizontal = horizontalPadding),
806842 color = NavigationBarDefaults .containerColor,
807843 shape = actualShape,
@@ -841,7 +877,7 @@ class MainActivity : ComponentActivity() {
841877 val miniPlayerH = with (density) { MiniPlayerHeight .toPx() }
842878 val totalSheetHeightWhenContentCollapsedPx = if (showPlayerContentInitially && ! shouldHideMiniPlayer) miniPlayerH else 0f
843879
844- val bottomMargin = innerPadding.calculateBottomPadding()
880+ val bottomMargin = miniPlayerBottomMargin
845881
846882 val spacerPx = with (density) { MiniPlayerBottomSpacer .toPx() }
847883 val sheetCollapsedTargetY = screenHeightPx - totalSheetHeightWhenContentCollapsedPx - with (density){ bottomMargin.toPx() } - spacerPx
@@ -863,7 +899,7 @@ class MainActivity : ComponentActivity() {
863899 hideMiniPlayer = shouldHideMiniPlayer,
864900 containerHeight = containerHeight,
865901 navController = navController,
866- isNavBarHidden = shouldHideNavigationBar
902+ isNavBarHidden = isNavBarEffectivelyHidden
867903 )
868904 } else {
869905 UnifiedPlayerSheet (
@@ -873,7 +909,7 @@ class MainActivity : ComponentActivity() {
873909 hideMiniPlayer = shouldHideMiniPlayer,
874910 containerHeight = containerHeight,
875911 navController = navController,
876- isNavBarHidden = shouldHideNavigationBar
912+ isNavBarHidden = isNavBarEffectivelyHidden
877913 )
878914 }
879915
0 commit comments