From 038dc4addbfc56091ea4619cc9397d4bffd2a599 Mon Sep 17 00:00:00 2001 From: Mincheol Shin Date: Sat, 6 Apr 2024 15:58:26 +0900 Subject: [PATCH 1/4] [GroovinExpandableBox] Fix : Modifier factory functions must use the receiver Modifier instance More... --- .../main/java/io/groovin/expandablebox/ExpandableBoxState.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt index 892475f..a03fbcc 100644 --- a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt +++ b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt @@ -404,7 +404,7 @@ internal fun Modifier.expandableBoxSwipeable( state.processNewAnchors(oldAnchors, anchors) } - Modifier.draggable( + this.draggable( orientation = orientation, enabled = enabled, reverseDirection = reverseDirection, From 958c9c5e490c980c8974618b7afd2214645b6671 Mon Sep 17 00:00:00 2001 From: Mincheol Shin Date: Sat, 6 Apr 2024 16:24:03 +0900 Subject: [PATCH 2/4] [GroovinExpandableBox] Fix to mutableFloatStateOf, fraction name to fromToProgress --- .../expandablebox/ExpandableBoxState.kt | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt index a03fbcc..a5dbc53 100644 --- a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt +++ b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.Saver @@ -72,9 +73,9 @@ open class ExpandableBoxState( val offset: State get() = offsetState val overflow: State get() = overflowState - private val offsetState = mutableStateOf(0f) - private val overflowState = mutableStateOf(0f) - private val absoluteOffset = mutableStateOf(0f) + private val offsetState = mutableFloatStateOf(0f) + private val overflowState = mutableFloatStateOf(0f) + private val absoluteOffset = mutableFloatStateOf(0f) private val animationTarget = mutableStateOf(null) internal var anchors by mutableStateOf(emptyMap()) @@ -94,8 +95,8 @@ open class ExpandableBoxState( requireNotNull(initialOffset) { "The initial value must have an associated anchor." } - offsetState.value = initialOffset - absoluteOffset.value = initialOffset + offsetState.floatValue = initialOffset + absoluteOffset.floatValue = initialOffset } } @@ -150,29 +151,29 @@ open class ExpandableBoxState( internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f }) - internal var velocityThreshold by mutableStateOf(0f) + internal var velocityThreshold by mutableFloatStateOf(0f) internal var resistance: ResistanceConfig? by mutableStateOf(null) internal val draggableState = DraggableState { - val newAbsolute = absoluteOffset.value + it + val newAbsolute = absoluteOffset.floatValue + it val clamped = newAbsolute.coerceIn(minBound, maxBound) val overflow = newAbsolute - clamped val resistanceDelta = resistance?.computeResistance(overflow) ?: 0f - offsetState.value = clamped + resistanceDelta - overflowState.value = overflow - absoluteOffset.value = newAbsolute + offsetState.floatValue = clamped + resistanceDelta + overflowState.floatValue = overflow + absoluteOffset.floatValue = newAbsolute } private suspend fun snapInternalToOffset(target: Float) { draggableState.drag { - dragBy(target - absoluteOffset.value) + dragBy(target - absoluteOffset.floatValue) } } private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec) { draggableState.drag { - var prevValue = absoluteOffset.value + var prevValue = absoluteOffset.floatValue animationTarget.value = target isAnimationRunning = true try { @@ -206,17 +207,17 @@ open class ExpandableBoxState( val bounds = findBounds(offset.value, anchors.keys) val from: ExpandableBoxStateValue val to: ExpandableBoxStateValue - val fraction: Float + val fromToProgress: Float when (bounds.size) { 0 -> { from = completedValue to = completedValue - fraction = 1f + fromToProgress = 1f } 1 -> { from = anchors.getValue(bounds[0]) to = anchors.getValue(bounds[0]) - fraction = 1f + fromToProgress = 1f } else -> { val (a, b) = @@ -227,10 +228,10 @@ open class ExpandableBoxState( } from = anchors.getValue(a) to = anchors.getValue(b) - fraction = (offset.value - a) / (b - a) + fromToProgress = (offset.value - a) / (b - a) } } - return ExpandableBoxSwipeProgress(from, to, fraction) + return ExpandableBoxSwipeProgress(from, to, fromToProgress) } val direction: Float @@ -256,7 +257,7 @@ open class ExpandableBoxState( } animateInternalToOffset(targetOffset, anim) } finally { - val endOffset = absoluteOffset.value + val endOffset = absoluteOffset.floatValue val endValue = anchors // fighting rounding error once again, anchor should be as close as 0.5 pixels .filterKeys { anchorOffset -> abs(anchorOffset - endOffset) < 0.5f } @@ -285,9 +286,9 @@ open class ExpandableBoxState( } fun performDrag(delta: Float): Float { - val potentiallyConsumed = absoluteOffset.value + delta + val potentiallyConsumed = absoluteOffset.floatValue + delta val clamped = potentiallyConsumed.coerceIn(minBound, maxBound) - val deltaToConsume = clamped - absoluteOffset.value + val deltaToConsume = clamped - absoluteOffset.floatValue if (abs(deltaToConsume) > 0) { draggableState.dispatchRawDelta(deltaToConsume) } @@ -310,23 +311,23 @@ class ExpandableBoxSwipeProgress( val from: ExpandableBoxStateValue, val to: ExpandableBoxStateValue, /*@FloatRange(from = 0.0, to = 1.0)*/ - val fraction: Float + val fromToProgress: Float ) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is ExpandableBoxSwipeProgress) return false - return !(from != other.from || to != other.to || fraction != other.fraction) + return !(from != other.from || to != other.to || fromToProgress != other.fromToProgress) } override fun hashCode(): Int { var result = from.hashCode() result = 31 * result + (to.hashCode()) - result = 31 * result + fraction.hashCode() + result = 31 * result + fromToProgress.hashCode() return result } override fun toString(): String { - return "ExpandableBoxSwipeProgress(from=$from, to=$to, fraction=$fraction)" + return "ExpandableBoxSwipeProgress(from=$from, to=$to, fraction=$fromToProgress)" } } From 132f86814049ca6407576546235546cd49e61f5f Mon Sep 17 00:00:00 2001 From: Mincheol Shin Date: Sat, 6 Apr 2024 17:52:05 +0900 Subject: [PATCH 3/4] [GroovinExpandableBox] Update Music Sample - Add BottomBar : Hiding when MusicPlayer is animated on fullscren mode --- README.md | 2 +- .../expandablebox/ExpandableBoxState.kt | 2 +- .../sampleapp/GroovinNavGraph.kt | 33 +++---- .../expandablebox/sampleapp/MainScreen.kt | 9 +- .../sampleapp/music/MusicBottomBar.kt | 64 +++++++++++++ .../sampleapp/music/MusicListScreen.kt | 29 +++--- .../sampleapp/music/MusicPlayerScreen.kt | 13 ++- .../sampleapp/music/MusicSampleScreen.kt | 95 ++++++++++++------- 8 files changed, 165 insertions(+), 82 deletions(-) create mode 100644 sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicBottomBar.kt diff --git a/README.md b/README.md index 1ffcb1a..64c055e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This library offers a Box Composable that can be expanded/reduced through up/dow | MusicPlayer Sample | Article Page Sample | Map Sample | |:---------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------:| -| MusicPlayerSample | ArticlePageSample | MapSample | +| MusicPlayerSample | ArticlePageSample | MapSample | ## Including in your project diff --git a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt index a5dbc53..6480589 100644 --- a/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt +++ b/expandablebox/src/main/java/io/groovin/expandablebox/ExpandableBoxState.kt @@ -327,7 +327,7 @@ class ExpandableBoxSwipeProgress( } override fun toString(): String { - return "ExpandableBoxSwipeProgress(from=$from, to=$to, fraction=$fromToProgress)" + return "ExpandableBoxSwipeProgress(from=$from, to=$to, fromToProgress=$fromToProgress)" } } diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/GroovinNavGraph.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/GroovinNavGraph.kt index 470015f..adef58f 100644 --- a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/GroovinNavGraph.kt +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/GroovinNavGraph.kt @@ -18,11 +18,10 @@ import io.groovin.expandablebox.sampleapp.music.MusicSampleScreen object GroovinDestination { - const val Main = "Main" - const val MusicBottomExpandBox = "MusicBottomExpandBox" - const val MusicUpExpandBox = "MusicUpExpandBox" - const val ArticleExpandBox = "ArticleExpandBox" - const val MapExpandBox = "MapExpandBox" + const val MAIN = "Main" + const val MUSIC_SAMPLE = "MusicSample" + const val ARTICLE_SAMPLE = "ArticleSample" + const val MAP_SAMPLE = "MapSample" } val LocalNavAction = compositionLocalOf { error("can't find GroovinAction") } @@ -33,7 +32,7 @@ fun GroovinNavGraph( ) { NavHost( navController = navController, - startDestination = GroovinDestination.Main, + startDestination = GroovinDestination.MAIN, enterTransition = { fadeIn(animationSpec = tween(700)) + slideIntoContainer( towards = AnimatedContentTransitionScope.SlideDirection.Companion.Up, @@ -53,20 +52,17 @@ fun GroovinNavGraph( ) } ) { - composable(GroovinDestination.Main) { + composable(GroovinDestination.MAIN) { MainScreen() } - composable(GroovinDestination.MusicBottomExpandBox) { - MusicSampleScreen(false) + composable(GroovinDestination.MUSIC_SAMPLE) { + MusicSampleScreen() } - composable(GroovinDestination.MusicUpExpandBox) { - MusicSampleScreen(true) - } - composable(GroovinDestination.ArticleExpandBox) { + composable(GroovinDestination.ARTICLE_SAMPLE) { ArticleSampleScreen() } composable( - route = "${GroovinDestination.MapExpandBox}?" + + route = "${GroovinDestination.MAP_SAMPLE}?" + "nestedScrollOption={nestedScrollOption}", arguments = listOf( navArgument("nestedScrollOption") { defaultValue = 0 } @@ -80,16 +76,13 @@ fun GroovinNavGraph( class GroovinAction(private val navController: NavHostController?) { val moveToMusicBottomExpandBox: () -> Unit = { - navController?.navigate(GroovinDestination.MusicBottomExpandBox) - } - val moveToMusicUpExpandBox: () -> Unit = { - navController?.navigate(GroovinDestination.MusicUpExpandBox) + navController?.navigate(GroovinDestination.MUSIC_SAMPLE) } val moveToArticleExpandBox: () -> Unit = { - navController?.navigate(GroovinDestination.ArticleExpandBox) + navController?.navigate(GroovinDestination.ARTICLE_SAMPLE) } val moveToMapExpandBox: (Int) -> Unit = { nestedScrollOption -> - navController?.navigate(GroovinDestination.MapExpandBox + "?nestedScrollOption=$nestedScrollOption") + navController?.navigate(GroovinDestination.MAP_SAMPLE + "?nestedScrollOption=$nestedScrollOption") } val moveToBack: () -> Unit = { navController?.popBackStack() diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/MainScreen.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/MainScreen.kt index ba94521..48df681 100644 --- a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/MainScreen.kt +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/MainScreen.kt @@ -37,18 +37,11 @@ fun MainScreen() { ) { MainHeader() MainItem( - text = "Sample 1 : Music Player (Downside)", + text = "Sample 1 : Music Player", onClick = { navAction.moveToMusicBottomExpandBox() } ) - MainItem( - text = "Sample 2 : Music Player (Upside)", - onClick = { - navAction.moveToMusicUpExpandBox() - } - ) - MainItem( text = "Sample 2 : Article Page", onClick = { diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicBottomBar.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicBottomBar.kt new file mode 100644 index 0000000..640885d --- /dev/null +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicBottomBar.kt @@ -0,0 +1,64 @@ +package io.groovin.expandablebox.sampleapp.music + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountCircle +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp + + +@Composable +fun MusicBottomBar( + modifier: Modifier = Modifier, + onMenuClick: ((Int) -> Unit)? = null +) { + Row( + modifier = modifier + ) { + MusicBottomBarItem(imageVector = Icons.Default.PlayArrow) { + onMenuClick?.invoke(0) + } + MusicBottomBarItem(imageVector = Icons.Default.Favorite) { + onMenuClick?.invoke(1) + } + MusicBottomBarItem(imageVector = Icons.Default.AccountCircle) { + onMenuClick?.invoke(2) + } + } +} + +@Composable +private fun RowScope.MusicBottomBarItem( + imageVector: ImageVector, + onClick: () -> Unit +) { + Column( + modifier = Modifier + .weight(1f) + .fillMaxHeight() + .clickable { + onClick() + }, + verticalArrangement = Arrangement.Center + ) { + Image( + modifier = Modifier + .size(24.dp) + .align(Alignment.CenterHorizontally), + imageVector = imageVector, + contentDescription = null + ) + } +} diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicListScreen.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicListScreen.kt index 6dba8eb..9ab1021 100644 --- a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicListScreen.kt +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicListScreen.kt @@ -2,15 +2,13 @@ package io.groovin.expandablebox.sampleapp.music import androidx.compose.foundation.Image import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -26,18 +24,23 @@ import io.groovin.expandablebox.sampleapp.R @Composable fun MusicListScreen( + modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), onItemClick: ((Int) -> Unit)? = null ) { - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()) + LazyColumn( + modifier = modifier, + contentPadding = contentPadding ) { - for (i in 0 .. 100) { + items( + count = 100, + key = { index -> "MusicSongItem$index" }, + contentType = { _ -> "MusicSongItem" } + ) { index -> MusicListItem( - title = "Music Song $i Item", + title = "Music Song $index Item", onClick = { - onItemClick?.invoke(i) + onItemClick?.invoke(index) } ) } @@ -53,11 +56,11 @@ private fun MusicListItem( Row( modifier = Modifier .fillMaxWidth() - .padding(8.dp) - .clip(RoundedCornerShape(4.dp)) + .clip(RoundedCornerShape(8.dp)) .clickable { onClick() } + .padding(12.dp) ) { Image( modifier = Modifier diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicPlayerScreen.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicPlayerScreen.kt index 2790020..2f89557 100644 --- a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicPlayerScreen.kt +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicPlayerScreen.kt @@ -37,11 +37,10 @@ fun MusicPlayerScreen( progress: Float, progressState: ExpandableBoxStateValue, minimizedHeight: Dp, - isUpside: Boolean, foldClick: () -> Unit, playClick: () -> Unit ) { - val constraintSets = remember(progressState) { getConstraintSets(progressState, if (isUpside) -minimizedHeight else minimizedHeight) } + val constraintSets = remember(progressState) { getConstraintSets(progressState, minimizedHeight) } MotionLayout( start = constraintSets.first, end = constraintSets.second, @@ -59,7 +58,7 @@ fun MusicPlayerScreen( onClick = { foldClick() } ) { Icon( - imageVector = if (isUpside) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, + imageVector = Icons.Default.KeyboardArrowDown, contentDescription = null ) } @@ -112,8 +111,8 @@ private fun hideConstraintSet(foldHeight: Dp) = ConstraintSet { val foldButton = createRefFor("foldButton") val playButton = createRefFor("playButton") constrain(poster) { - width = Dimension.value(80.dp) - height = Dimension.value(80.dp) + width = Dimension.value(40.dp) + height = Dimension.value(40.dp) translationY = foldHeight / 2 start.linkTo(parent.start) top.linkTo(parent.top) @@ -151,8 +150,8 @@ private fun foldConstraintSet() = ConstraintSet { val foldButton = createRefFor("foldButton") val playButton = createRefFor("playButton") constrain(poster) { - width = Dimension.value(80.dp) - height = Dimension.value(80.dp) + width = Dimension.value(60.dp) + height = Dimension.value(60.dp) start.linkTo(parent.start) top.linkTo(parent.top) bottom.linkTo(parent.bottom) diff --git a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicSampleScreen.kt b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicSampleScreen.kt index 5cb0d7b..cad7d31 100644 --- a/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicSampleScreen.kt +++ b/sampleapp/src/main/java/io/groovin/expandablebox/sampleapp/music/MusicSampleScreen.kt @@ -5,12 +5,18 @@ import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -32,18 +38,21 @@ import kotlinx.coroutines.launch private val MusicPlayerScreenBackgroundColor = Pink80 @Composable -fun MusicSampleScreen( - isUpside: Boolean -) { +fun MusicSampleScreen() { val coroutineScope = rememberCoroutineScope() var selectedItemIndex by remember { mutableIntStateOf(0) } val context = LocalContext.current - val minimizedHeight = remember { 100.dp } + val playerCompactHeight = remember { 64.dp } + val bottomBarHeight = remember { 80.dp } Box(modifier = Modifier.fillMaxSize()) { val expandableBoxState = rememberExpandableBoxState( initialValue = ExpandableBoxStateValue.HalfExpand ) + val expandableProgress = remember { + mutableFloatStateOf(1f) + } MusicListScreen( + contentPadding = PaddingValues(bottom = playerCompactHeight + bottomBarHeight), onItemClick = { index -> selectedItemIndex = index if (expandableBoxState.completedValue == ExpandableBoxStateValue.Fold) { @@ -53,40 +62,62 @@ fun MusicSampleScreen( } } ) - ExpandableBox( - modifier = Modifier - .align(if (isUpside) Alignment.TopCenter else Alignment.BottomCenter) - .fillMaxWidth(), - expandableBoxState = expandableBoxState, - swipeDirection = if (isUpside) ExpandableBoxSwipeDirection.SwipeDownToExpand else ExpandableBoxSwipeDirection.SwipeUpToExpand, - foldHeight = 0.dp, - halfExpandHeight = minimizedHeight - ) { - MusicPlayerScreen( - modifier = Modifier.background(MusicPlayerScreenBackgroundColor), - selectedItemIndex = selectedItemIndex, - progress = progress, - progressState = progressState, - minimizedHeight = minimizedHeight, - isUpside = isUpside, - foldClick = { + Column(modifier = Modifier.align(Alignment.BottomCenter)) { + ExpandableBox( + modifier = Modifier + .fillMaxWidth(), + expandableBoxState = expandableBoxState, + swipeDirection = ExpandableBoxSwipeDirection.SwipeUpToExpand, + foldHeight = 0.dp, + halfExpandHeight = playerCompactHeight + ) { + expandableProgress.floatValue = this.progress + MusicPlayerScreen( + modifier = Modifier.background(MusicPlayerScreenBackgroundColor), + selectedItemIndex = selectedItemIndex, + progress = progress, + progressState = progressState, + minimizedHeight = playerCompactHeight, + foldClick = { + coroutineScope.launch { + expandableBoxState.animateTo(ExpandableBoxStateValue.HalfExpand) + } + }, + playClick = { + Toast.makeText(context, "Play it!", Toast.LENGTH_SHORT).show() + } + ) + SyncStatusBarColor(progressState, colorScheme.background) + BackHandler( + enabled = (completedState == ExpandableBoxStateValue.Expand) || (expandableBoxState.isAnimationRunning) + ) { + if (expandableBoxState.isAnimationRunning) return@BackHandler coroutineScope.launch { expandableBoxState.animateTo(ExpandableBoxStateValue.HalfExpand) } - }, - playClick = { - Toast.makeText(context, "Play it!", Toast.LENGTH_SHORT).show() } - ) - SyncStatusBarColor(progressState, colorScheme.background) - BackHandler( - enabled = (completedState == ExpandableBoxStateValue.Expand) || (expandableBoxState.isAnimationRunning) - ) { - if (expandableBoxState.isAnimationRunning) return@BackHandler - coroutineScope.launch { - expandableBoxState.animateTo(ExpandableBoxStateValue.HalfExpand) + } + val bottomBarDynamicHeight by remember(expandableBoxState.progressValue, expandableProgress.floatValue) { + derivedStateOf { + when (expandableBoxState.progressValue) { + ExpandableBoxStateValue.Expand -> 0.dp + ExpandableBoxStateValue.Expanding -> bottomBarHeight * (1f - expandableProgress.floatValue) + else -> bottomBarHeight + } } } + Box( + modifier = Modifier.height(bottomBarDynamicHeight) + ) { + MusicBottomBar( + modifier = Modifier + .align(Alignment.TopCenter) + .fillMaxWidth() + .wrapContentHeight(align = Alignment.Top, unbounded = true) + .height(bottomBarHeight) + .background(MusicPlayerScreenBackgroundColor) + ) + } } } } From 7e321bb848d2cdbe19294063999a05e18f353870 Mon Sep 17 00:00:00 2001 From: Mincheol Shin Date: Sat, 6 Apr 2024 17:57:23 +0900 Subject: [PATCH 4/4] [GroovinExpandableBox] Release 1.2.2 - update version to 1.2.2 - update Compose BOM to 2024.04.00 --- build.gradle | 2 +- expandablebox/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d0b76e5..b3410dc 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { androidx_core_version = '1.12.0' - compose_bom_version = '2024.02.02' + compose_bom_version = '2024.04.00' compose_compiler_version = '1.5.8' kotlin_plugin_version = '1.9.22' } diff --git a/expandablebox/build.gradle b/expandablebox/build.gradle index 31fc0c0..c7755be 100644 --- a/expandablebox/build.gradle +++ b/expandablebox/build.gradle @@ -59,7 +59,7 @@ afterEvaluate { from components.release groupId = 'io.groovin' artifactId = 'groovinexpandablebox' - version = '1.2.1' + version = '1.2.2' } } }