perf: 优化设置页面的性能
This commit is contained in:
parent
711d8a19c5
commit
5c25a4657d
10 changed files with 259 additions and 181 deletions
|
|
@ -34,7 +34,7 @@ android {
|
||||||
applicationId = "cn.super12138.todo"
|
applicationId = "cn.super12138.todo"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 730
|
versionCode = 733
|
||||||
versionName = "2.1.2"
|
versionName = "2.1.2"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
|
||||||
|
|
@ -224,8 +224,6 @@ fun TodoEditorPage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Spacer(Modifier.size(20.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
package cn.super12138.todo.ui.pages.settings
|
package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Balance
|
import androidx.compose.material.icons.outlined.Balance
|
||||||
import androidx.compose.material.icons.outlined.Numbers
|
import androidx.compose.material.icons.outlined.Numbers
|
||||||
|
|
@ -50,61 +48,68 @@ fun SettingsAbout(
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
|
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
) {
|
||||||
var clickCount by remember { mutableIntStateOf(0) }
|
item {
|
||||||
var lastClickTime by remember { mutableLongStateOf(0L) }
|
var clickCount by remember { mutableIntStateOf(0) }
|
||||||
|
var lastClickTime by remember { mutableLongStateOf(0L) }
|
||||||
|
|
||||||
LaunchedEffect(clickCount) {
|
LaunchedEffect(clickCount) {
|
||||||
if (clickCount > 0) {
|
if (clickCount > 0) {
|
||||||
lastClickTime = System.currentTimeMillis()
|
lastClickTime = System.currentTimeMillis()
|
||||||
val currentClickTime = lastClickTime
|
val currentClickTime = lastClickTime
|
||||||
delay(300L)
|
delay(300L)
|
||||||
|
|
||||||
if (currentClickTime == lastClickTime) {
|
if (currentClickTime == lastClickTime) {
|
||||||
clickCount = 0
|
clickCount = 0
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsItem(
|
|
||||||
leadingIcon = Icons.Outlined.Numbers,
|
|
||||||
title = stringResource(R.string.pref_app_version),
|
|
||||||
description = SystemUtils.getAppVersion(context),
|
|
||||||
onClick = {
|
|
||||||
clickCount++
|
|
||||||
if (clickCount == 5) {
|
|
||||||
if ((System.currentTimeMillis() % 2) == 0.toLong()) {
|
|
||||||
Toast.makeText(context, "🍨", Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "✨", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
clickCount = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
leadingIcon = Icons.Outlined.Person4,
|
leadingIcon = Icons.Outlined.Numbers,
|
||||||
title = stringResource(R.string.pref_developer),
|
title = stringResource(R.string.pref_app_version),
|
||||||
description = stringResource(R.string.developer_name),
|
description = SystemUtils.getAppVersion(context),
|
||||||
onClick = { uriHandler.openUri(Constants.DEVELOPER_GITHUB) }
|
onClick = {
|
||||||
)
|
clickCount++
|
||||||
SettingsItem(
|
if (clickCount == 5) {
|
||||||
leadingIcon = GitHubIcon,
|
if ((System.currentTimeMillis() % 2) == 0.toLong()) {
|
||||||
title = stringResource(R.string.pref_view_on_github),
|
Toast.makeText(context, "🍨", Toast.LENGTH_SHORT).show()
|
||||||
description = stringResource(R.string.pref_view_on_github_desc),
|
} else {
|
||||||
onClick = { uriHandler.openUri(Constants.GITHUB_REPO) }
|
Toast.makeText(context, "✨", Toast.LENGTH_SHORT).show()
|
||||||
)
|
}
|
||||||
SettingsItem(
|
clickCount = 0
|
||||||
leadingIcon = Icons.Outlined.Balance,
|
}
|
||||||
title = stringResource(R.string.pref_licence),
|
}
|
||||||
description = stringResource(R.string.pref_licence_desc),
|
)
|
||||||
onClick = toLicencePage
|
}
|
||||||
)
|
item {
|
||||||
|
SettingsItem(
|
||||||
|
leadingIcon = Icons.Outlined.Person4,
|
||||||
|
title = stringResource(R.string.pref_developer),
|
||||||
|
description = stringResource(R.string.developer_name),
|
||||||
|
onClick = { uriHandler.openUri(Constants.DEVELOPER_GITHUB) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
SettingsItem(
|
||||||
|
leadingIcon = GitHubIcon,
|
||||||
|
title = stringResource(R.string.pref_view_on_github),
|
||||||
|
description = stringResource(R.string.pref_view_on_github_desc),
|
||||||
|
onClick = { uriHandler.openUri(Constants.GITHUB_REPO) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
SettingsItem(
|
||||||
|
leadingIcon = Icons.Outlined.Balance,
|
||||||
|
title = stringResource(R.string.pref_licence),
|
||||||
|
description = stringResource(R.string.pref_licence_desc),
|
||||||
|
onClick = toLicencePage
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,11 +4,9 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.FileDownload
|
import androidx.compose.material.icons.outlined.FileDownload
|
||||||
import androidx.compose.material.icons.outlined.FileUpload
|
import androidx.compose.material.icons.outlined.FileUpload
|
||||||
|
|
@ -110,30 +108,34 @@ fun SettingsData(
|
||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
) {
|
||||||
SettingsItem(
|
item {
|
||||||
leadingIcon = Icons.Outlined.FileDownload,
|
SettingsItem(
|
||||||
title = stringResource(R.string.pref_backup),
|
leadingIcon = Icons.Outlined.FileDownload,
|
||||||
description = stringResource(R.string.pref_backup_desc),
|
title = stringResource(R.string.pref_backup),
|
||||||
onClick = {
|
description = stringResource(R.string.pref_backup_desc),
|
||||||
backupLauncher.launch("Todo-backup-${SystemUtils.getTime()}.zip")
|
onClick = {
|
||||||
}
|
backupLauncher.launch("Todo-backup-${SystemUtils.getTime()}.zip")
|
||||||
)
|
}
|
||||||
SettingsItem(
|
)
|
||||||
leadingIcon = Icons.Outlined.FileUpload,
|
}
|
||||||
title = stringResource(R.string.pref_restore),
|
item {
|
||||||
description = stringResource(R.string.pref_restore_desc),
|
SettingsItem(
|
||||||
onClick = {
|
leadingIcon = Icons.Outlined.FileUpload,
|
||||||
restoreLauncher.launch(arrayOf("application/zip"))
|
title = stringResource(R.string.pref_restore),
|
||||||
}
|
description = stringResource(R.string.pref_restore_desc),
|
||||||
)
|
onClick = {
|
||||||
|
restoreLauncher.launch(arrayOf("application/zip"))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmDialog(
|
ConfirmDialog(
|
||||||
visible = showRestoreDialog,
|
visible = showRestoreDialog,
|
||||||
icon = Icons.Outlined.RestartAlt,
|
icon = Icons.Outlined.RestartAlt,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package cn.super12138.todo.ui.pages.settings
|
package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.Sort
|
import androidx.compose.material.icons.automirrored.outlined.Sort
|
||||||
import androidx.compose.material.icons.outlined.Checklist
|
import androidx.compose.material.icons.outlined.Checklist
|
||||||
|
|
@ -59,43 +57,54 @@ fun SettingsInterface(
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
|
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
) {
|
||||||
SettingsCategory(stringResource(R.string.pref_category_todo_list))
|
item {
|
||||||
SwitchSettingsItem(
|
SettingsCategory(stringResource(R.string.pref_category_todo_list))
|
||||||
checked = showCompleted,
|
}
|
||||||
leadingIcon = Icons.Outlined.Checklist,
|
item {
|
||||||
title = stringResource(R.string.pref_show_completed),
|
SwitchSettingsItem(
|
||||||
description = stringResource(R.string.pref_show_completed_desc),
|
checked = showCompleted,
|
||||||
onCheckedChange = { scope.launch { DataStoreManager.setShowCompleted(it) } },
|
leadingIcon = Icons.Outlined.Checklist,
|
||||||
)
|
title = stringResource(R.string.pref_show_completed),
|
||||||
SettingsItem(
|
description = stringResource(R.string.pref_show_completed_desc),
|
||||||
leadingIcon = Icons.AutoMirrored.Outlined.Sort,
|
onCheckedChange = { scope.launch { DataStoreManager.setShowCompleted(it) } },
|
||||||
title = stringResource(R.string.pref_sorting_method),
|
)
|
||||||
description = SortingMethod.fromId(sortingMethod).getDisplayName(context),
|
}
|
||||||
onClick = { showSortingMethodDialog = true }
|
item {
|
||||||
)
|
SettingsItem(
|
||||||
|
leadingIcon = Icons.AutoMirrored.Outlined.Sort,
|
||||||
|
title = stringResource(R.string.pref_sorting_method),
|
||||||
|
description = SortingMethod.fromId(sortingMethod).getDisplayName(context),
|
||||||
|
onClick = { showSortingMethodDialog = true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
SettingsCategory(stringResource(R.string.pref_category_global))
|
item {
|
||||||
SwitchSettingsItem(
|
SettingsCategory(stringResource(R.string.pref_category_global))
|
||||||
checked = secureMode,
|
}
|
||||||
leadingIcon = Icons.Outlined.Shield,
|
item {
|
||||||
title = stringResource(R.string.pref_secure_mode),
|
SwitchSettingsItem(
|
||||||
description = stringResource(R.string.pref_secure_mode_desc),
|
checked = secureMode,
|
||||||
onCheckedChange = { scope.launch { DataStoreManager.setSecureMode(it) } }
|
leadingIcon = Icons.Outlined.Shield,
|
||||||
)
|
title = stringResource(R.string.pref_secure_mode),
|
||||||
SwitchSettingsItem(
|
description = stringResource(R.string.pref_secure_mode_desc),
|
||||||
checked = hapticFeedback,
|
onCheckedChange = { scope.launch { DataStoreManager.setSecureMode(it) } }
|
||||||
leadingIcon = Icons.Outlined.Vibration,
|
)
|
||||||
title = stringResource(R.string.pref_haptic_feedback),
|
}
|
||||||
description = stringResource(R.string.pref_haptic_feedback_desc),
|
item {
|
||||||
onCheckedChange = { scope.launch { DataStoreManager.setHapticFeedback(it) } }
|
SwitchSettingsItem(
|
||||||
)
|
checked = hapticFeedback,
|
||||||
SettingsPlainBox(stringResource(R.string.pref_haptic_feedback_more_info))
|
leadingIcon = Icons.Outlined.Vibration,
|
||||||
|
title = stringResource(R.string.pref_haptic_feedback),
|
||||||
|
description = stringResource(R.string.pref_haptic_feedback_desc),
|
||||||
|
onCheckedChange = { scope.launch { DataStoreManager.setHapticFeedback(it) } }
|
||||||
|
)
|
||||||
|
SettingsPlainBox(stringResource(R.string.pref_haptic_feedback_more_info))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package cn.super12138.todo.ui.pages.settings
|
package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.ColorLens
|
import androidx.compose.material.icons.outlined.ColorLens
|
||||||
import androidx.compose.material.icons.outlined.Dns
|
import androidx.compose.material.icons.outlined.Dns
|
||||||
|
|
@ -14,6 +12,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||||
|
|
@ -33,38 +32,46 @@ fun SettingsMain(
|
||||||
LargeTopAppBarScaffold(
|
LargeTopAppBarScaffold(
|
||||||
title = stringResource(R.string.page_settings),
|
title = stringResource(R.string.page_settings),
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
onBack = onNavigateUp
|
onBack = onNavigateUp,
|
||||||
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
) {
|
||||||
SettingsItem(
|
item {
|
||||||
leadingIcon = Icons.Outlined.ColorLens,
|
SettingsItem(
|
||||||
title = stringResource(R.string.pref_appearance),
|
leadingIcon = Icons.Outlined.ColorLens,
|
||||||
description = stringResource(R.string.pref_appearance_desc),
|
title = stringResource(R.string.pref_appearance),
|
||||||
onClick = toAppearancePage
|
description = stringResource(R.string.pref_appearance_desc),
|
||||||
)
|
onClick = toAppearancePage
|
||||||
SettingsItem(
|
)
|
||||||
leadingIcon = Icons.Outlined.ViewComfy,
|
}
|
||||||
title = stringResource(R.string.pref_interface_interaction),
|
item {
|
||||||
description = stringResource(R.string.pref_interface_interaction_desc),
|
SettingsItem(
|
||||||
onClick = toInterfacePage
|
leadingIcon = Icons.Outlined.ViewComfy,
|
||||||
)
|
title = stringResource(R.string.pref_interface_interaction),
|
||||||
SettingsItem(
|
description = stringResource(R.string.pref_interface_interaction_desc),
|
||||||
leadingIcon = Icons.Outlined.Dns,
|
onClick = toInterfacePage
|
||||||
title = stringResource(R.string.pref_data),
|
)
|
||||||
description = stringResource(R.string.pref_data_desc),
|
}
|
||||||
onClick = toDataPage
|
item {
|
||||||
)
|
SettingsItem(
|
||||||
SettingsItem(
|
leadingIcon = Icons.Outlined.Dns,
|
||||||
leadingIcon = Icons.Outlined.Info,
|
title = stringResource(R.string.pref_data),
|
||||||
title = stringResource(R.string.pref_about),
|
description = stringResource(R.string.pref_data_desc),
|
||||||
description = stringResource(R.string.pref_about_desc),
|
onClick = toDataPage
|
||||||
onClick = toAboutPage
|
)
|
||||||
)
|
}
|
||||||
|
item {
|
||||||
|
SettingsItem(
|
||||||
|
leadingIcon = Icons.Outlined.Info,
|
||||||
|
title = stringResource(R.string.pref_about),
|
||||||
|
description = stringResource(R.string.pref_about_desc),
|
||||||
|
onClick = toAboutPage
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -82,6 +84,55 @@ fun RowSettingsItem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LazyRowSettingsItem(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
leadingIcon: (@Composable () -> Unit)? = null,
|
||||||
|
title: String,
|
||||||
|
description: String? = null,
|
||||||
|
trailingContent: (@Composable () -> Unit)? = null,
|
||||||
|
shape: Shape = MaterialTheme.shapes.large,
|
||||||
|
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
|
||||||
|
verticalAlignment: Alignment.Vertical = Alignment.Top,
|
||||||
|
fadedEdgeWidth: Dp,
|
||||||
|
maskColor: Color = MaterialTheme.colorScheme.background,
|
||||||
|
content: LazyListScope.() -> Unit
|
||||||
|
) {
|
||||||
|
MoreContentSettingsItem(
|
||||||
|
leadingIcon = leadingIcon,
|
||||||
|
title = title,
|
||||||
|
description = description,
|
||||||
|
trailingContent = trailingContent,
|
||||||
|
shape = shape,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
LazyRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
// 渲染到离屏缓冲区是为了确保边缘淡出的 alpha 效果仅应用于文本本身,而不影响该可组合项下方绘制的内容(例如窗口背景)。
|
||||||
|
.graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
|
||||||
|
.drawWithContent {
|
||||||
|
// 需要调用 drawContent,因为它用于将内容绘制到布局中的接收器作用域,允许内容穿插在其他画布操作之间绘制。
|
||||||
|
// 如果未调用 drawContent,则不会绘制该布局的内容。
|
||||||
|
drawContent()
|
||||||
|
drawFadedEdge(
|
||||||
|
edgeWidth = fadedEdgeWidth,
|
||||||
|
maskColor = maskColor,
|
||||||
|
leftEdge = true
|
||||||
|
)
|
||||||
|
drawFadedEdge(
|
||||||
|
edgeWidth = fadedEdgeWidth,
|
||||||
|
maskColor = maskColor,
|
||||||
|
leftEdge = false
|
||||||
|
)
|
||||||
|
},
|
||||||
|
horizontalArrangement = horizontalArrangement,
|
||||||
|
verticalAlignment = verticalAlignment,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MoreContentSettingsItem(
|
fun MoreContentSettingsItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,7 @@ fun SwitchSettingsItem(
|
||||||
modifier = Modifier.padding(start = TodoDefaults.settingsItemHorizontalPadding / 2)
|
modifier = Modifier.padding(start = TodoDefaults.settingsItemHorizontalPadding / 2)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = { onCheckedChange(!checked) },
|
||||||
onCheckedChange(!checked)
|
|
||||||
},
|
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.ui.pages.settings.components.RowSettingsItem
|
import cn.super12138.todo.ui.pages.settings.components.LazyRowSettingsItem
|
||||||
import cn.super12138.todo.ui.theme.DarkMode
|
import cn.super12138.todo.ui.theme.DarkMode
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -20,38 +20,44 @@ fun DarkModePicker(
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val isInDarkTheme = isSystemInDarkTheme()
|
val isInDarkTheme = isSystemInDarkTheme()
|
||||||
RowSettingsItem(
|
LazyRowSettingsItem(
|
||||||
title = stringResource(R.string.pref_dark_mode),
|
title = stringResource(R.string.pref_dark_mode),
|
||||||
description = stringResource(R.string.pref_dark_mode_desc),
|
description = stringResource(R.string.pref_dark_mode_desc),
|
||||||
horizontalArrangement = Arrangement.spacedBy(5.dp),
|
horizontalArrangement = Arrangement.spacedBy(5.dp),
|
||||||
fadedEdgeWidth = 8.dp,
|
fadedEdgeWidth = 8.dp,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
DarkModeItem(
|
item {
|
||||||
icon = DarkMode.FollowSystem.icon,
|
DarkModeItem(
|
||||||
name = DarkMode.FollowSystem.getDisplayName(context),
|
icon = DarkMode.FollowSystem.icon,
|
||||||
contentColor = if (isInDarkTheme) Color.White else Color.Black,
|
name = DarkMode.FollowSystem.getDisplayName(context),
|
||||||
containerColor = if (isInDarkTheme) Color.Black else Color.White,
|
contentColor = if (isInDarkTheme) Color.White else Color.Black,
|
||||||
selected = currentDarkMode == DarkMode.FollowSystem,
|
containerColor = if (isInDarkTheme) Color.Black else Color.White,
|
||||||
onSelect = { onDarkModeChange(DarkMode.FollowSystem) }
|
selected = currentDarkMode == DarkMode.FollowSystem,
|
||||||
)
|
onSelect = { onDarkModeChange(DarkMode.FollowSystem) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
DarkModeItem(
|
item {
|
||||||
icon = DarkMode.Light.icon,
|
DarkModeItem(
|
||||||
name = DarkMode.Light.getDisplayName(context),
|
icon = DarkMode.Light.icon,
|
||||||
contentColor = Color.Black,
|
name = DarkMode.Light.getDisplayName(context),
|
||||||
containerColor = Color.White,
|
contentColor = Color.Black,
|
||||||
selected = currentDarkMode == DarkMode.Light,
|
containerColor = Color.White,
|
||||||
onSelect = { onDarkModeChange(DarkMode.Light) }
|
selected = currentDarkMode == DarkMode.Light,
|
||||||
)
|
onSelect = { onDarkModeChange(DarkMode.Light) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
DarkModeItem(
|
item {
|
||||||
icon = DarkMode.Dark.icon,
|
DarkModeItem(
|
||||||
name = DarkMode.Dark.getDisplayName(context),
|
icon = DarkMode.Dark.icon,
|
||||||
contentColor = Color.White,
|
name = DarkMode.Dark.getDisplayName(context),
|
||||||
containerColor = Color.Black,
|
contentColor = Color.White,
|
||||||
selected = currentDarkMode == DarkMode.Dark,
|
containerColor = Color.Black,
|
||||||
onSelect = { onDarkModeChange(DarkMode.Dark) }
|
selected = currentDarkMode == DarkMode.Dark,
|
||||||
)
|
onSelect = { onDarkModeChange(DarkMode.Dark) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.ui.pages.settings.components.RowSettingsItem
|
import cn.super12138.todo.ui.pages.settings.components.LazyRowSettingsItem
|
||||||
import cn.super12138.todo.ui.theme.ContrastLevel
|
import cn.super12138.todo.ui.theme.ContrastLevel
|
||||||
import cn.super12138.todo.ui.theme.DarkMode
|
import cn.super12138.todo.ui.theme.DarkMode
|
||||||
import cn.super12138.todo.ui.theme.PaletteStyle
|
import cn.super12138.todo.ui.theme.PaletteStyle
|
||||||
|
|
@ -27,7 +27,7 @@ fun PalettePicker(
|
||||||
PaletteStyle.entries.toList()
|
PaletteStyle.entries.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
RowSettingsItem(
|
LazyRowSettingsItem(
|
||||||
title = stringResource(R.string.pref_palette_style),
|
title = stringResource(R.string.pref_palette_style),
|
||||||
description = stringResource(R.string.pref_palette_style_desc),
|
description = stringResource(R.string.pref_palette_style_desc),
|
||||||
horizontalArrangement = Arrangement.spacedBy(5.dp),
|
horizontalArrangement = Arrangement.spacedBy(5.dp),
|
||||||
|
|
@ -35,18 +35,20 @@ fun PalettePicker(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
paletteOptions.forEach { paletteStyle ->
|
paletteOptions.forEach { paletteStyle ->
|
||||||
PaletteItem(
|
item {
|
||||||
isDynamicColor = isDynamicColor,
|
PaletteItem(
|
||||||
isDark = when (isDarkMode) {
|
isDynamicColor = isDynamicColor,
|
||||||
DarkMode.FollowSystem -> isSystemInDarkTheme()
|
isDark = when (isDarkMode) {
|
||||||
DarkMode.Light -> false
|
DarkMode.FollowSystem -> isSystemInDarkTheme()
|
||||||
DarkMode.Dark -> true
|
DarkMode.Light -> false
|
||||||
},
|
DarkMode.Dark -> true
|
||||||
paletteStyle = paletteStyle,
|
},
|
||||||
selected = currentPalette == paletteStyle,
|
paletteStyle = paletteStyle,
|
||||||
contrastLevel = contrastLevel,
|
selected = currentPalette == paletteStyle,
|
||||||
onSelect = { onPaletteChange(paletteStyle) }
|
contrastLevel = contrastLevel,
|
||||||
)
|
onSelect = { onPaletteChange(paletteStyle) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue