From fe0c667af51063bbb1374acd2c9011108c4d426f Mon Sep 17 00:00:00 2001 From: HuanCheng65 <22636177+HuanCheng65@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:02:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=87=AA=E5=AE=9A=E4=B9=89=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E8=89=B2=E6=94=AF=E6=8C=81=E7=9B=B4=E6=8E=A5=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E9=A2=9C=E8=89=B2=E7=9A=84=E5=8D=81=E5=85=AD=E8=BF=9B?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/page/settings/theme/AppThemePage.kt | 105 ++++++++++++++++-- .../tieba/post/ui/widgets/compose/Dialogs.kt | 93 +++++++++++----- .../tieba/post/utils/extension/ColorExt.kt | 8 ++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 169 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/utils/extension/ColorExt.kt diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/settings/theme/AppThemePage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/settings/theme/AppThemePage.kt index 21842658..f6c00951 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/settings/theme/AppThemePage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/settings/theme/AppThemePage.kt @@ -1,6 +1,8 @@ package com.huanchengfly.tieba.post.ui.page.settings.theme import android.os.Build +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -15,17 +17,24 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.sizeIn +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.Checkbox import androidx.compose.material.Icon +import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme +import androidx.compose.material.OutlinedTextField import androidx.compose.material.Text +import androidx.compose.material.TextFieldDefaults import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.BorderColor import androidx.compose.material.icons.rounded.Check import androidx.compose.material.icons.rounded.ColorLens import androidx.compose.material.icons.rounded.Colorize @@ -34,6 +43,7 @@ import androidx.compose.material.icons.rounded.PhotoSizeSelectActual import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -47,7 +57,9 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp +import androidx.core.graphics.toColorInt import androidx.datastore.preferences.core.booleanPreferencesKey import com.github.panpf.sketch.compose.AsyncImage import com.github.panpf.sketch.fetch.newFileUri @@ -74,6 +86,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.TitleCentredToolbar import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState import com.huanchengfly.tieba.post.utils.ThemeUtil import com.huanchengfly.tieba.post.utils.appPreferences +import com.huanchengfly.tieba.post.utils.extension.toHexString import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator @@ -119,21 +132,95 @@ fun AppThemePage( dialogState = customPrimaryColorDialogState, title = { Text(text = stringResource(id = R.string.title_custom_theme)) }, content = { + var useInput by remember { mutableStateOf(false) } + Column( modifier = Modifier .fillMaxWidth() - .padding(16.dp) + .padding(horizontal = 16.dp) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(8.dp) ) { - HarmonyColorPicker( - harmonyMode = ColorHarmonyMode.ANALOGOUS, - color = HsvColor.from(customPrimaryColor), - onColorChanged = { - customPrimaryColor = it.toColor() - }, - modifier = Modifier.size(350.dp) - ) + AnimatedContent( + targetState = useInput, + label = "", + modifier = Modifier + .wrapContentHeight() + .animateContentSize() + ) { input -> + if (input) { + var inputHexColor by remember { mutableStateOf(customPrimaryColor.toHexString()) } + val lastValidColor by produceState( + initialValue = customPrimaryColor, + inputHexColor + ) { + if ("^#([0-9a-fA-F]{6})$".toRegex().matches(inputHexColor)) { + value = Color(inputHexColor.toColorInt()) + } + } + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.fillMaxWidth() + ) { + Spacer( + modifier = Modifier + .size(48.dp) + .clip(CircleShape) + .background(lastValidColor) + ) + OutlinedTextField( + value = inputHexColor, + onValueChange = { + if ("^#([0-9a-fA-F]{0,6})$".toRegex().matches(it)) { + inputHexColor = it + } + }, + maxLines = 1, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + modifier = Modifier.weight(1f), + colors = TextFieldDefaults.outlinedTextFieldColors( + cursorColor = ExtendedTheme.colors.primary, + focusedBorderColor = ExtendedTheme.colors.primary, + focusedLabelColor = ExtendedTheme.colors.primary + ) + ) + IconButton( + onClick = { + customPrimaryColor = Color(inputHexColor.toColorInt()) + useInput = false + } + ) { + Icon( + imageVector = Icons.Rounded.Check, + contentDescription = stringResource(id = R.string.button_sure_default) + ) + } + } + } else { + Box { + HarmonyColorPicker( + harmonyMode = ColorHarmonyMode.ANALOGOUS, + color = HsvColor.from(customPrimaryColor), + onColorChanged = { + customPrimaryColor = it.toColor() + }, + modifier = Modifier.sizeIn(maxWidth = 320.dp, maxHeight = 320.dp) + ) + + IconButton( + onClick = { useInput = true }, + modifier = Modifier.align(Alignment.TopEnd) + ) { + Icon( + imageVector = Icons.Rounded.BorderColor, + contentDescription = stringResource(id = R.string.desc_input_color) + ) + } + } + } + } Row( verticalAlignment = Alignment.CenterVertically, diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Dialogs.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Dialogs.kt index 8267f1ee..da514057 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Dialogs.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Dialogs.kt @@ -1,5 +1,6 @@ package com.huanchengfly.tieba.post.ui.widgets.compose +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -8,6 +9,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -29,7 +31,6 @@ import androidx.compose.runtime.saveable.listSaver import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester @@ -39,6 +40,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension +import androidx.constraintlayout.compose.Visibility import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.arch.BaseComposeActivity.Companion.LocalWindowSizeClass import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme @@ -239,7 +243,6 @@ fun ConfirmDialog( * * @param onValueChange 输入框内容变化时的回调,返回true表示允许变化,false表示不允许变化 */ -@OptIn(ExperimentalComposeUiApi::class) @Composable fun PromptDialog( onConfirm: (String) -> Unit, @@ -361,40 +364,72 @@ fun Dialog( dismissOnClickOutside = cancelableOnTouchOutside ) ) { - Column( - modifier = modifier - .fillMaxWidth( - fraction = if (windowWidthSizeClass == WindowWidthSizeClass.Compact) { - 1f - } else { - 0.6f - } - ) - .padding(16.dp) - .background( - color = ExtendedTheme.colors.windowBackground, - shape = RoundedCornerShape(24.dp) - ) - .padding(vertical = 24.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - ProvideContentColor(color = ExtendedTheme.colors.text) { - if (title != null) { - Box( - modifier = Modifier - .padding(horizontal = 24.dp) - .align(Alignment.CenterHorizontally) - ) { - ProvideTextStyle(value = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold)) { - dialogScope.title() + ProvideContentColor(color = ExtendedTheme.colors.text) { + ConstraintLayout( + modifier = modifier + .wrapContentHeight() + .animateContentSize() + .fillMaxWidth( + fraction = if (windowWidthSizeClass == WindowWidthSizeClass.Compact) { + 1f + } else { + 0.6f + } + ) + .padding(16.dp) + .background( + color = ExtendedTheme.colors.windowBackground, + shape = RoundedCornerShape(24.dp) + ) + .padding(vertical = 24.dp), + ) { + val (titleRef, contentRef, buttonsRef) = createRefs() + Column( + modifier = Modifier + .constrainAs(titleRef) { + top.linkTo(parent.top) + start.linkTo(parent.start) + end.linkTo(parent.end) + width = Dimension.fillToConstraints + visibility = if (title == null) { + Visibility.Gone + } else { + Visibility.Visible + } + } + ) { + if (title != null) { + Box( + modifier = Modifier + .padding(horizontal = 24.dp) + .align(Alignment.CenterHorizontally) + ) { + ProvideTextStyle(value = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold)) { + dialogScope.title() + } } } } - Box(modifier = Modifier.align(Alignment.CenterHorizontally)) { + Column( + modifier = Modifier + .constrainAs(contentRef) { + top.linkTo(titleRef.bottom, margin = 16.dp, goneMargin = 0.dp) + bottom.linkTo(buttonsRef.top, margin = 16.dp, goneMargin = 0.dp) + start.linkTo(parent.start) + end.linkTo(parent.end) + height = Dimension.preferredWrapContent + } + ) { dialogScope.content() } Column( modifier = Modifier + .constrainAs(buttonsRef) { + start.linkTo(parent.start) + end.linkTo(parent.end) + bottom.linkTo(parent.bottom) + width = Dimension.fillToConstraints + } .padding(horizontal = 24.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/extension/ColorExt.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/extension/ColorExt.kt new file mode 100644 index 00000000..7d0f7c03 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/extension/ColorExt.kt @@ -0,0 +1,8 @@ +package com.huanchengfly.tieba.post.utils.extension + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb + +fun Color.toHexString(): String { + return "#${Integer.toHexString(toArgb()).substring(2)}" +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b2cd7ae..ac02ef04 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -517,4 +517,5 @@ 显示 状态栏遮罩 开启后非白色主题状态栏将略微变暗 + 手动输入颜色