Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Setting] 라이트 모드 / 다크 모드 설정 카드 UI #61

Merged
merged 9 commits into from
Jul 22, 2023
3 changes: 3 additions & 0 deletions core/designsystem/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ android {
namespace = "com.droidknights.app2023.core.designsystem"
}

dependencies {
implementation(libs.androidx.appcompat)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.droidknights.app2023.core.designsystem.theme

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf

private val DarkColorScheme = darkColorScheme(
primary = Neon01,
Expand All @@ -17,12 +20,17 @@ private val LightColorScheme = lightColorScheme(
tertiary = Yellow01
)

val LocalDarkTheme = compositionLocalOf { true }

@Composable
fun KnightsTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
MaterialTheme(
typography = Typography,
content = content
)
CompositionLocalProvider(LocalDarkTheme provides darkTheme) {
MaterialTheme(
typography = Typography,
content = content
)
}
}
2 changes: 1 addition & 1 deletion core/designsystem/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="Theme.DroidKnights2023" parent="android:Theme.Material.Light.NoActionBar" />
<style name="Theme.DroidKnights2023" parent="Theme.AppCompat.DayNight.NoActionBar" />
wisemuji marked this conversation as resolved.
Show resolved Hide resolved

<style name="Theme.DroidKnights2023.NoStatusBar">
<item name="android:statusBarColor">@android:color/transparent</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package com.droidknights.app2023.feature.home.navigation
import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.droidknights.app2023.feature.home.HomeScreen

fun NavController.navigateHome() {
navigate(HomeRoute.route)
fun NavController.navigateHome(navOptions: NavOptions) {
navigate(HomeRoute.route, navOptions)
}

fun NavGraphBuilder.homeNavGraph(
Expand Down
1 change: 1 addition & 0 deletions feature/main/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies {
implementation(project(":feature:contributor"))

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.lifecycle.runtimeCompose)
implementation(libs.androidx.lifecycle.viewModelCompose)
Expand Down
1 change: 1 addition & 0 deletions feature/main/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<activity
android:name=".MainActivity"
android:exported="true"
android:configChanges="uiMode"
android:theme="@style/Theme.DroidKnights2023.NoStatusBar">

<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
package com.droidknights.app2023.feature.main

import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.view.WindowCompat
import com.droidknights.app2023.core.designsystem.theme.KnightsTheme
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

class MainActivity : AppCompatActivity() {
private var isDarkTheme by mutableStateOf(false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

WindowCompat.setDecorFitsSystemWindows(window, false)

setContent {
KnightsTheme {
KnightsTheme(darkTheme = isDarkTheme) {
MainScreen()
}
}
}

private fun isNightModeEnabled(uiMode: Int): Boolean {
val currentNightMode = uiMode and Configuration.UI_MODE_NIGHT_MASK
return currentNightMode == Configuration.UI_MODE_NIGHT_YES
}

// FIXME : configurationChanges를 사용하지 않고 깜빡이지 않게 테마를 바꾸는 방법 찾기
laco-dev marked this conversation as resolved.
Show resolved Hide resolved
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
isDarkTheme = isNightModeEnabled(newConfig.uiMode)
}
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
package com.droidknights.app2023.feature.main

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.navigation.NavDestination
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.droidknights.app2023.feature.contributor.navigation.ContributorRoute
import com.droidknights.app2023.feature.home.navigation.HomeRoute
import com.droidknights.app2023.feature.home.navigation.navigateHome
import com.droidknights.app2023.feature.setting.navigation.SettingRoute
import com.droidknights.app2023.feature.setting.navigation.navigateSetting

internal class MainNavigator(
startTab: MainTab = MainTab.HOME,
val navController: NavHostController,
) {
val startDestination: String = when (startTab) {
MainTab.HOME -> HomeRoute.route
MainTab.SETTING -> SettingRoute.route
MainTab.TEMP -> "temp"
}
private val currentDestination: NavDestination?
@Composable get() = navController
.currentBackStackEntryAsState().value?.destination
val startDestination: String
@Composable get() = currentDestination?.route ?: HomeRoute.route

val currentTab: MainTab?
@Composable get() = when (currentDestination?.route) {
HomeRoute.route -> MainTab.HOME
SettingRoute.route -> MainTab.SETTING
"temp" -> MainTab.TEMP
else -> null
}

var currentTab: MainTab by mutableStateOf(startTab)
private set

fun navigate(tab: MainTab) {
if (tab == currentTab) return
val navOptions = navOptions {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}

when (tab) {
MainTab.SETTING -> navController.navigateSetting()
MainTab.HOME -> navController.navigateHome()
MainTab.SETTING -> navController.navigateSetting(navOptions)
MainTab.HOME -> navController.navigateHome(navOptions)
MainTab.TEMP -> navController.navigate("temp") // TODO: ???
}
currentTab = tab
}

fun navigateContributor() {
Expand All @@ -57,8 +68,7 @@ internal class MainNavigator(

@Composable
internal fun rememberMainNavigator(
starTab: MainTab = MainTab.HOME,
navController: NavHostController = rememberNavController(),
): MainNavigator = remember(navController) {
MainNavigator(starTab, navController)
MainNavigator(navController)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal fun MainScreen(navigator: MainNavigator = rememberMainNavigator()) {
) {
NavHost(
navController = navigator.navController,
startDestination = navigator.startDestination,
startDestination = navigator.startDestination
) {
settingNavGraph()
homeNavGraph(
Expand Down Expand Up @@ -80,7 +80,7 @@ internal fun MainScreen(navigator: MainNavigator = rememberMainNavigator()) {
@Composable
private fun MainBottomBar(
tabs: List<MainTab>,
currentTab: MainTab,
currentTab: MainTab?,
onTabSelected: (MainTab) -> Unit,
) {
Row(
Expand Down
1 change: 1 addition & 0 deletions feature/setting/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ android {

dependencies {
implementation(libs.androidx.compose.navigation)
implementation(libs.androidx.appcompat)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,146 @@
package com.droidknights.app2023.feature.setting

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.RadioButtonDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.droidknights.app2023.core.designsystem.theme.KnightsTheme
import com.droidknights.app2023.core.designsystem.theme.LocalDarkTheme

@Composable
internal fun SettingScreen() {

Column(
Modifier
.background(color = Color(0xFFF9F9F9))
.padding(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
LightDarkThemeCard()
}
}

@Composable
private fun LightDarkThemeCard(darkTheme: Boolean = LocalDarkTheme.current) {
val changeDarkTheme: (Boolean) -> Unit = {
val mode = if (it) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
AppCompatDelegate.setDefaultNightMode(mode)
}

CompositionLocalProvider(LocalContentColor provides Color(0xFF000000)) {
Surface(
shape = RoundedCornerShape(32.dp),
color = Color(0xFFFFFFFF),
shadowElevation = 2.dp,
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카드 UI는 공통으로 관리하면 어떨까요? 꼭 이 PR이 아니여도 됩니다.

Column {
Text(
text = stringResource(id = R.string.setting),
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(top = 24.dp, start = 24.dp)
)
Spacer(modifier = Modifier.height(40.dp))

Row(
modifier = Modifier
.padding(horizontal = 8.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
val cardModifier = Modifier.weight(1f)
ThemeCard(
selected = !darkTheme,
titleRes = R.string.light_mode,
imageRes = R.drawable.img_light_mode,
onClick = { changeDarkTheme(false) },
modifier = cardModifier,
)
ThemeCard(
selected = darkTheme,
titleRes = R.string.dark_mode,
imageRes = R.drawable.img_dark_mode,
onClick = { changeDarkTheme(true) },
modifier = cardModifier,
)
}
}
}
}
}

@Composable
private fun ThemeCard(
selected: Boolean,
@StringRes titleRes: Int,
@DrawableRes imageRes: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Surface(
shape = RoundedCornerShape(16.dp),
onClick = onClick,
) {
Image(
painter = painterResource(id = imageRes),
contentDescription = null,
modifier = Modifier.aspectRatio(1f)
)
}

Text(
text = stringResource(id = titleRes),
modifier = Modifier.padding(top = 16.dp, bottom = 8.dp),
style = MaterialTheme.typography.titleSmall,
)

RadioButton(
selected = selected,
onClick = onClick,
colors = RadioButtonDefaults.colors(
selectedColor = Color(0xFF000000),
unselectedColor = Color(0xFF5E5E5E)
)
)
}
}


@Preview
@Composable
private fun SettingScreenPreview() {
KnightsTheme {
SettingScreen()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package com.droidknights.app2023.feature.setting.navigation

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.droidknights.app2023.feature.setting.SettingScreen

fun NavController.navigateSetting() {
navigate(SettingRoute.route)
fun NavController.navigateSetting(navOptions: NavOptions) {
navigate(SettingRoute.route, navOptions)
}

fun NavGraphBuilder.settingNavGraph() {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions feature/setting/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="setting">설정</string>
<string name="light_mode">라이트 모드</string>
<string name="dark_mode">다크 모드</string>
</resources>
Loading