Skip to content

Commit

Permalink
feat(settings): 添加外观与个性化设置
Browse files Browse the repository at this point in the history
里面有动态配色和主题样式两个设置的实现
后续还有待优化 SharedPreferences 的读写方式
  • Loading branch information
Super12138 committed Feb 5, 2025
1 parent e729125 commit 32e2292
Show file tree
Hide file tree
Showing 21 changed files with 522 additions and 33 deletions.
5 changes: 5 additions & 0 deletions app/src/main/kotlin/cn/super12138/todo/TodoApp.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package cn.super12138.todo

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import cn.super12138.todo.logic.database.TodoDatabase
import cn.super12138.todo.ui.pages.crash.CrashHandler

class TodoApp : Application() {
private val database by lazy { TodoDatabase.getDatabase(this) }

companion object {
@SuppressLint("StaticFieldLeak")
lateinit var context: Context
lateinit var db: TodoDatabase
}

override fun onCreate() {
super.onCreate()

db = database
context = applicationContext

val crashHandler = CrashHandler(applicationContext)
Thread.setDefaultUncaughtExceptionHandler(crashHandler)
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/kotlin/cn/super12138/todo/constants/Constants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cn.super12138.todo.constants

object Constants {
const val SP_NAME = "cn.super12138.todo_preferences"

const val PREF_DYNAMIC_COLOR = "dynamic_color"
const val PREF_DYNAMIC_COLOR_DEFAULT = true

const val PREF_PALETTE_STYLE = "palette_style"
const val PREF_PALETTE_STYLE_DEFAULT = 1 // TonalSpot
}
14 changes: 14 additions & 0 deletions app/src/main/kotlin/cn/super12138/todo/constants/GlobalValues.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cn.super12138.todo.constants

import cn.super12138.todo.utils.SPDelegates

object GlobalValues {
var dynamicColor: Boolean by SPDelegates(
Constants.PREF_DYNAMIC_COLOR,
Constants.PREF_DYNAMIC_COLOR_DEFAULT
)
var paletteStyle: Int by SPDelegates(
Constants.PREF_PALETTE_STYLE,
Constants.PREF_PALETTE_STYLE_DEFAULT
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import cn.super12138.todo.ui.pages.editor.TodoEditorPage
import cn.super12138.todo.ui.pages.main.MainPage
import cn.super12138.todo.ui.pages.settings.SettingsAbout
import cn.super12138.todo.ui.pages.settings.SettingsAboutLicence
import cn.super12138.todo.ui.pages.settings.SettingsAppearance
import cn.super12138.todo.ui.pages.settings.SettingsMain
import cn.super12138.todo.ui.theme.materialSharedAxisXIn
import cn.super12138.todo.ui.theme.materialSharedAxisXOut
Expand Down Expand Up @@ -82,10 +83,17 @@ fun TodoNavigation(
composable(TodoScreen.SettingsMain.name) {
SettingsMain(
onNavigateUp = { navController.navigateUp() },
toAppearancePage = { navController.navigate(TodoScreen.SettingsAppearance.name) },
toAboutPage = { navController.navigate(TodoScreen.SettingsAbout.name) }
)
}

composable(TodoScreen.SettingsAppearance.name) {
SettingsAppearance(
onNavigateUp = { navController.navigateUp() }
)
}

composable(TodoScreen.SettingsAbout.name) {
SettingsAbout(
onNavigateUp = { navController.navigateUp() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ enum class TodoScreen {
Main,
TodoEditor,
SettingsMain,
SettingsAppearance,
SettingsAbout,
SettingsAboutLicence
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import cn.super12138.todo.R
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.DefaultSettingsItem
import cn.super12138.todo.ui.pages.settings.components.SettingsItem
import cn.super12138.todo.utils.getAppVersion

@OptIn(ExperimentalMaterial3Api::class)
Expand All @@ -29,8 +29,7 @@ fun SettingsAbout(
title = stringResource(R.string.pref_about),
onBack = onNavigateUp,
scrollBehavior = scrollBehavior,
modifier = modifier
.nestedScroll(scrollBehavior.nestedScrollConnection),
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { innerPadding ->
val context = LocalContext.current
Column(
Expand All @@ -39,17 +38,17 @@ fun SettingsAbout(
.padding(innerPadding)
.verticalScroll(rememberScrollState())
) {
DefaultSettingsItem(
SettingsItem(
title = stringResource(R.string.pref_app_version),
description = getAppVersion(context),
enableClick = false
)
DefaultSettingsItem(
SettingsItem(
title = stringResource(R.string.pref_developer),
description = stringResource(R.string.developer_name),
enableClick = false
)
DefaultSettingsItem(
SettingsItem(
title = stringResource(R.string.pref_licence),
description = stringResource(R.string.pref_licence_desc),
onClick = toLicencePage
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cn.super12138.todo.ui.pages.settings

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ColorLens
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import cn.super12138.todo.R
import cn.super12138.todo.constants.Constants
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.SwitchSettingsItem
import cn.super12138.todo.ui.pages.settings.components.palette.PalettePicker
import cn.super12138.todo.ui.theme.appPaletteStyle
import cn.super12138.todo.ui.theme.isDynamicColorEnable

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsAppearance(
onNavigateUp: () -> Unit,
modifier: Modifier = Modifier
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
LargeTopAppBarScaffold(
title = stringResource(R.string.pref_appearance),
onBack = onNavigateUp,
scrollBehavior = scrollBehavior,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { innerPadding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.verticalScroll(rememberScrollState())
) {
SwitchSettingsItem(
key = Constants.PREF_DYNAMIC_COLOR,
default = Constants.PREF_DYNAMIC_COLOR_DEFAULT,
leadingIcon = Icons.Outlined.ColorLens,
title = stringResource(R.string.pref_appearance_dynamic_color),
description = stringResource(R.string.pref_appearance_dynamic_color_desc),
onCheckedChange = { isDynamicColorEnable = it },
)

PalettePicker(onPaletteChange = { appPaletteStyle = it })
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ColorLens
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.TopAppBarDefaults
Expand All @@ -14,12 +15,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import cn.super12138.todo.R
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.DefaultSettingsItem
import cn.super12138.todo.ui.pages.settings.components.SettingsItem

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsMain(
onNavigateUp: () -> Unit,
toAppearancePage: () -> Unit,
toAboutPage: () -> Unit,
modifier: Modifier = Modifier
) {
Expand All @@ -35,7 +37,13 @@ fun SettingsMain(
.padding(innerPadding)
.verticalScroll(rememberScrollState())
) {
DefaultSettingsItem(
SettingsItem(
leadingIcon = Icons.Outlined.ColorLens,
title = stringResource(R.string.pref_appearance),
description = stringResource(R.string.pref_appearance_desc),
onClick = toAppearancePage
)
SettingsItem(
leadingIcon = Icons.Outlined.Info,
title = stringResource(R.string.pref_about),
description = stringResource(R.string.pref_about_desc),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun DefaultSettingsItem(
fun SettingsItem(
leadingIcon: ImageVector? = null,
title: String,
description: String? = null,
enableClick: Boolean = true,
onClick: () -> Unit = {},
modifier: Modifier = Modifier
) {
DefaultSettingsItem(
SettingsItem(
leadingIcon = leadingIcon,
title = title,
description = description,
Expand All @@ -40,7 +40,7 @@ fun DefaultSettingsItem(
}

@Composable
fun DefaultSettingsItem(
fun SettingsItem(
leadingIcon: ImageVector? = null,
title: String,
description: String? = null,
Expand All @@ -49,7 +49,7 @@ fun DefaultSettingsItem(
onClick: () -> Unit = {},
modifier: Modifier = Modifier
) {
DefaultSettingsItem(
SettingsItem(
leadingIcon = {
leadingIcon?.let {
Icon(
Expand All @@ -70,7 +70,7 @@ fun DefaultSettingsItem(
}

@Composable
fun DefaultSettingsItem(
fun SettingsItem(
leadingIcon: (@Composable () -> Unit)? = null,
title: String,
description: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,40 @@ package cn.super12138.todo.ui.pages.settings.components

import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import cn.super12138.todo.ui.pages.settings.state.rememberPrefBooleanState

@Composable
fun SwitchSettingsItem(
key: String,
default: Boolean,
leadingIcon: ImageVector? = null,
title: String,
description: String? = null,
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
onClick: () -> Unit = {},
modifier: Modifier = Modifier
) {
DefaultSettingsItem(
var switchState by rememberPrefBooleanState(key, default)
SettingsItem(
leadingIcon = leadingIcon,
title = title,
description = description,
trailingContent = {
Switch(
checked = checked,
onCheckedChange = onCheckedChange,
modifier = modifier,
checked = switchState,
onCheckedChange = {
switchState = it
onCheckedChange(it)
}
)
},
onClick = onClick,
onClick = {
switchState = !switchState
onCheckedChange(switchState)
},
modifier = modifier
)
}
Loading

0 comments on commit 32e2292

Please sign in to comment.