Use ButtonGroup for even more juicy button morph animations
This commit is contained in:
@@ -5,10 +5,10 @@ import androidx.compose.animation.animateColorAsState
|
|||||||
import androidx.compose.animation.slideInVertically
|
import androidx.compose.animation.slideInVertically
|
||||||
import androidx.compose.animation.slideOutVertically
|
import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
|
import androidx.compose.material3.ButtonGroup
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.CircularWavyProgressIndicator
|
import androidx.compose.material3.CircularWavyProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
@@ -35,6 +36,7 @@ import androidx.compose.material3.TopAppBar
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.StrokeCap
|
import androidx.compose.ui.graphics.StrokeCap
|
||||||
@@ -210,21 +212,34 @@ fun TimerScreen(
|
|||||||
maxLines = 1
|
maxLines = 1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Row(
|
val interactionSources = remember { List(2) { MutableInteractionSource() } }
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
ButtonGroup(
|
||||||
|
overflowIndicator = {},
|
||||||
modifier = Modifier.padding(16.dp)
|
modifier = Modifier.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
|
customItem(
|
||||||
|
{
|
||||||
FilledTonalIconButton(
|
FilledTonalIconButton(
|
||||||
onClick = resetTimer,
|
onClick = resetTimer,
|
||||||
colors = IconButtonDefaults.filledTonalIconButtonColors(containerColor = colorContainer),
|
colors = IconButtonDefaults.filledTonalIconButtonColors(
|
||||||
|
containerColor = colorContainer
|
||||||
|
),
|
||||||
shapes = IconButtonDefaults.shapes(),
|
shapes = IconButtonDefaults.shapes(),
|
||||||
modifier = Modifier.size(96.dp)
|
interactionSource = interactionSources[0],
|
||||||
|
modifier = Modifier
|
||||||
|
.size(96.dp)
|
||||||
|
.animateWidth(interactionSources[0])
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painterResource(R.drawable.restart_large),
|
painterResource(R.drawable.restart_large),
|
||||||
contentDescription = "Restart"
|
contentDescription = "Restart"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
customItem(
|
||||||
|
{
|
||||||
FilledIconToggleButton(
|
FilledIconToggleButton(
|
||||||
onCheckedChange = { toggleTimer() },
|
onCheckedChange = { toggleTimer() },
|
||||||
checked = uiState.timerRunning,
|
checked = uiState.timerRunning,
|
||||||
@@ -233,7 +248,10 @@ fun TimerScreen(
|
|||||||
checkedContentColor = onColor
|
checkedContentColor = onColor
|
||||||
),
|
),
|
||||||
shapes = IconButtonDefaults.toggleableShapes(),
|
shapes = IconButtonDefaults.toggleableShapes(),
|
||||||
modifier = Modifier.size(width = 128.dp, height = 96.dp)
|
interactionSource = interactionSources[1],
|
||||||
|
modifier = Modifier
|
||||||
|
.size(width = 128.dp, height = 96.dp)
|
||||||
|
.animateWidth(interactionSources[1])
|
||||||
) {
|
) {
|
||||||
if (uiState.timerRunning) {
|
if (uiState.timerRunning) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -247,6 +265,9 @@ fun TimerScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +298,11 @@ fun TimerScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(showSystemUi = true)
|
@Preview(
|
||||||
|
widthDp = 384,
|
||||||
|
heightDp = 832,
|
||||||
|
showSystemUi = true
|
||||||
|
)
|
||||||
@Composable
|
@Composable
|
||||||
fun TimerScreenPreview() {
|
fun TimerScreenPreview() {
|
||||||
val uiState = UiState(
|
val uiState = UiState(
|
||||||
|
|||||||
Reference in New Issue
Block a user