dark mode-v3

This commit is contained in:
Eric85710 2026-04-21 16:05:28 +08:00
parent 4683f5ab22
commit e8dbf812d5
9 changed files with 102 additions and 24 deletions

View file

@ -13,12 +13,10 @@ 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.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Help
import androidx.compose.material.icons.filled.Devices import androidx.compose.material.icons.filled.Devices
import androidx.compose.material.icons.filled.Help import androidx.compose.material.icons.filled.Help
import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Subscriptions import androidx.compose.material.icons.filled.Subscriptions
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -32,13 +30,15 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.login_v3.home.setting.setting_detail_page.setting_devices_page import com.example.login_v3.home.setting.setting_detail_page.detail_UI.setting_devices_page
import com.example.login_v3.home.setting.setting_detail_page.setting_profile_page import com.example.login_v3.home.setting.setting_detail_page.detail_UI.setting_profile_page
import com.example.login_v3.home.setting.setting_detail_page.setting_subscription_page import com.example.login_v3.home.setting.setting_detail_page.detail_UI.setting_subscription_page
import com.example.login_v3.home.setting.setting_detail_page.setting_theme_page import com.example.login_v3.home.setting.setting_detail_page.detail_UI.setting_theme_page
import com.example.login_v3.home.setting.setting_detail_page.viewmodel.Theme_ViewModel
import com.example.login_v3.navigation.BottomBarViewModel import com.example.login_v3.navigation.BottomBarViewModel
@Composable @Composable
@ -113,12 +113,17 @@ fun SharedTransitionScope.setting_detail_Screen(
//spacing between content and title //spacing between content and title
Spacer(modifier = Modifier.height(26.dp)) Spacer(modifier = Modifier.height(26.dp))
NavHost( NavHost(
navController = setting_detail_page_navController, navController = setting_detail_page_navController,
startDestination = startRoute startDestination = startRoute
) { ) {
composable("setting_Profile") { setting_profile_page() } composable("setting_Profile") { setting_profile_page() }
composable("setting_Theme") { setting_theme_page() } composable("setting_Theme") {
val ThemeViewModel: Theme_ViewModel = viewModel()
setting_theme_page(ThemeViewModel)
}
composable("setting_Devices") { setting_devices_page() } composable("setting_Devices") { setting_devices_page() }
composable("setting_Subscription") { setting_subscription_page() } composable("setting_Subscription") { setting_subscription_page() }
} }

View file

@ -1,4 +1,4 @@
package com.example.login_v3.home.setting.setting_detail_page package com.example.login_v3.home.setting.setting_detail_page.detail_UI
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text import androidx.compose.material3.Text

View file

@ -1,4 +1,4 @@
package com.example.login_v3.home.setting.setting_detail_page package com.example.login_v3.home.setting.setting_detail_page.detail_UI
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background

View file

@ -1,4 +1,4 @@
package com.example.login_v3.home.setting.setting_detail_page package com.example.login_v3.home.setting.setting_detail_page.detail_UI
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text import androidx.compose.material3.Text

View file

@ -0,0 +1,58 @@
package com.example.login_v3.home.setting.setting_detail_page.detail_UI
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.selection.selectable
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.login_v3.home.setting.setting_detail_page.viewmodel.Theme_ViewModel
import com.example.login_v3.ui.theme.AppTheme
@Composable
fun setting_theme_page(
viewModel: Theme_ViewModel
){
val selectedTheme = viewModel.currentTheme.value
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "主題設定", style = MaterialTheme.typography.headlineMedium)
Spacer(modifier = Modifier.height(8.dp))
// 遍歷所有 Enum 選項
AppTheme.entries.forEach { theme ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.selectable(
selected = (theme == selectedTheme),
onClick = { viewModel.updateTheme(theme) }
)
.padding(8.dp)
) {
RadioButton(
selected = (theme == selectedTheme),
onClick = { viewModel.updateTheme(theme) }
)
Text(
text = when(theme) {
AppTheme.SYSTEM -> "跟隨系統設定"
AppTheme.LIGHT -> "淺色模式"
AppTheme.DARK -> "深色模式"
},
modifier = Modifier.padding(start = 8.dp)
)
}
}
}
}

View file

@ -1,12 +0,0 @@
package com.example.login_v3.home.setting.setting_detail_page
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun setting_theme_page(){
Column() {
Text(text = "setting_Theme_page")
}
}

View file

@ -0,0 +1,14 @@
package com.example.login_v3.home.setting.setting_detail_page.viewmodel
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import com.example.login_v3.ui.theme.AppTheme
class Theme_ViewModel : ViewModel() {
var currentTheme = mutableStateOf(AppTheme.SYSTEM)
private set
fun updateTheme(newTheme: AppTheme) {
currentTheme.value = newTheme
}
}

View file

@ -0,0 +1,7 @@
package com.example.login_v3.ui.theme
enum class AppTheme {
SYSTEM, // 跟隨系統
LIGHT, // 強制淺色
DARK // 強制深色
}

View file

@ -35,11 +35,17 @@ private val LightColorScheme = lightColorScheme(
@Composable @Composable
fun Login_V3Theme( fun Login_V3Theme(
darkTheme: Boolean = isSystemInDarkTheme(), appTheme: AppTheme = AppTheme.SYSTEM,
// Dynamic color is available on Android 12+ // Dynamic color is available on Android 12+
dynamicColor: Boolean = true, dynamicColor: Boolean = false,
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val darkTheme = when (appTheme) {
AppTheme.SYSTEM -> isSystemInDarkTheme()
AppTheme.LIGHT -> false
AppTheme.DARK -> true
}
val colorScheme = when { val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current val context = LocalContext.current