From c5ab1891e08397ccafe1403a43bbeaea9e23caff Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 18 Feb 2023 13:02:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=BE=D1=80=D0=BC=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20clickable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/megboyzz/dnevnik/Utils.kt | 2 +- .../megboyzz/dnevnik/screens/ui/Components.kt | 60 ++++--- .../dnevnik/screens/ui/SelectableItem.kt | 168 ++++++++++++++++++ 3 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/ru/megboyzz/dnevnik/screens/ui/SelectableItem.kt diff --git a/app/src/main/java/ru/megboyzz/dnevnik/Utils.kt b/app/src/main/java/ru/megboyzz/dnevnik/Utils.kt index 6cea75f..d664083 100644 --- a/app/src/main/java/ru/megboyzz/dnevnik/Utils.kt +++ b/app/src/main/java/ru/megboyzz/dnevnik/Utils.kt @@ -126,7 +126,7 @@ fun getMonthDaysBy(year: Int, month: Month, dayOfWeek: DayOfWeek): List{ @Composable fun Modifier.mainClickable( - radius: Dp, + radius: Dp = Dp.Unspecified, onClick: () -> Unit ) = this.clickable( interactionSource = remember { MutableInteractionSource() }, diff --git a/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/Components.kt b/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/Components.kt index ab85804..dde31f2 100644 --- a/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/Components.kt +++ b/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/Components.kt @@ -37,10 +37,12 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.* import androidx.compose.ui.viewinterop.AndroidView import androidx.navigation.NavController +import com.google.accompanist.navigation.animation.rememberAnimatedNavController import kotlinx.coroutines.launch import ru.megboyzz.dnevnik.* import ru.megboyzz.dnevnik.R @@ -174,21 +176,23 @@ fun BottomNavButton( color: Color = white, onClick: () -> Unit, ) { - Column( - Modifier - .clickable(onClick = onClick), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Image( - painter = icon, - contentDescription = "", - modifier = Modifier.padding(5.dp) - ) - Text( - text = text, - style = MainText, - color = color - ) + Box(Modifier.mainClickable(onClick = onClick, radius = 30.dp).padding(10.dp)) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Image( + painter = icon, + contentDescription = "", + modifier = Modifier.padding(5.dp) + ) + Text( + text = text, + style = MainText, + color = color, + overflow = TextOverflow.Ellipsis + ) + } } } @@ -441,6 +445,18 @@ fun MainTextField( ) } +@OptIn(ExperimentalAnimationApi::class) +@Preview +@Composable +fun DrawerPrev() { + val scaffoldState = rememberScaffoldState() + val navController = rememberAnimatedNavController() + Box(Modifier.background(mainBlue)) { + DrawerContent(navController = navController, scaffoldState = scaffoldState) + } + +} + @Composable fun DrawerMainButton( icon: Painter, @@ -448,24 +464,12 @@ fun DrawerMainButton( textColor: Color = white, onClick: () -> Unit = {} ) { - val interactionSource = MutableInteractionSource() - - val coroutineScope = rememberCoroutineScope() - - val scale = remember { - androidx.compose.animation.core.Animatable(1f) - } - - val animationDuration = 100 - val scaleDown = 0.9f - Column( modifier = Modifier .fillMaxWidth() .height(30.dp) //TODO Сделать нормальную анимаую клика(не квадратную) - .mainClickable(10.dp, onClick::invoke), - //.clickable(onClick = onClick), + .mainClickable(onClick = onClick), verticalArrangement = Arrangement.Center ) { Row( diff --git a/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/SelectableItem.kt b/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/SelectableItem.kt new file mode 100644 index 0000000..c207dc1 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/dnevnik/screens/ui/SelectableItem.kt @@ -0,0 +1,168 @@ +package ru.megboyzz.dnevnik.screens.ui + +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.CheckCircle +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch + +@Composable +fun SelectableItem( + modifier: Modifier = Modifier, + selected: Boolean, + title: String, + titleColor: Color = + if (selected) MaterialTheme.colors.primary + else MaterialTheme.colors.onSurface.copy(alpha = 0.2f), + titleSize: TextUnit = MaterialTheme.typography.h6.fontSize, + titleWeight: FontWeight = FontWeight.Medium, + subtitle: String? = null, + subtitleColor: Color = + if (selected) MaterialTheme.colors.onSurface + else MaterialTheme.colors.onSurface.copy(alpha = 0.2f), + borderWidth: Dp = 1.dp, + borderColor: Color = + if (selected) MaterialTheme.colors.primary + else MaterialTheme.colors.onSurface.copy(alpha = 0.2f), + borderShape: Shape = RoundedCornerShape(size = 10.dp), + icon: ImageVector = Icons.Default.CheckCircle, + iconColor: Color = + if (selected) MaterialTheme.colors.primary + else MaterialTheme.colors.onSurface.copy(alpha = 0.2f), + onClick: () -> Unit +) { + val scaleA = remember { Animatable(initialValue = 1f) } + val scaleB = remember { Animatable(initialValue = 1f) } + + val clickEnabled = remember { mutableStateOf(true) } + + LaunchedEffect(key1 = selected) { + if (selected) { + clickEnabled.value = false + + val jobA = launch { + scaleA.animateTo( + targetValue = 0.3f, + animationSpec = tween( + durationMillis = 50 + ) + ) + scaleA.animateTo( + targetValue = 1f, + animationSpec = spring( + dampingRatio = Spring.DampingRatioLowBouncy, + stiffness = Spring.StiffnessLow + ) + ) + } + val jobB = launch { + scaleB.animateTo( + targetValue = 0.9f, + animationSpec = tween( + durationMillis = 50 + ) + ) + scaleB.animateTo( + targetValue = 1f, + animationSpec = spring( + dampingRatio = Spring.DampingRatioLowBouncy, + stiffness = Spring.StiffnessLow + ) + ) + } + + jobA.join() + jobB.join() + clickEnabled.value = true + } + } + + Column( + modifier = modifier + .scale(scale = scaleB.value) + .border( + width = borderWidth, + color = borderColor, + shape = borderShape + ) + .clip(borderShape) + .clickable(enabled = clickEnabled.value) { + onClick() + } + ) { + Row( + modifier = Modifier.padding(start = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + modifier = Modifier.weight(8f), + text = title, + style = TextStyle( + color = titleColor, + fontSize = titleSize, + fontWeight = titleWeight + ), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + IconButton( + modifier = Modifier + .weight(2f) + .scale(scale = scaleA.value), + onClick = { + if (clickEnabled.value) { + onClick() + } + } + ) { + Icon( + imageVector = icon, + contentDescription = "Selectable Item Icon", + tint = iconColor + ) + } + } + if (subtitle != null) { + Text( + modifier = Modifier + .padding(horizontal = 12.dp) + .padding(bottom = 12.dp), + text = subtitle, + style = TextStyle( + color = subtitleColor + ), + maxLines = 3, + overflow = TextOverflow.Ellipsis + ) + } + } +}