feat: EdgeToEdge 개선 - 시스템 바 색상 통일 및 화면 공간 최적화 (v1.9.0)
- MainScreen.kt: 불필요한 windowInsetsPadding 제거로 화면 공간 확보 - DealListScreen.kt: TopAppBar에 statusBarsPadding 적용, FAB에 navigationBarsPadding 적용 - Theme.kt: 시스템 바 색상을 앱 surface 색상과 일치시켜 이질감 해소 - MainActivity.kt: setupEdgeToEdge 함수 간소화 및 중복 코드 제거 - version.json: 1.9.0 버전 업데이트
This commit is contained in:
@@ -24,8 +24,8 @@ android {
|
||||
applicationId = "com.hotdeal.alarm"
|
||||
minSdk = 31
|
||||
targetSdk = 35
|
||||
versionCode = 14
|
||||
versionName = "1.8.0"
|
||||
versionCode = 15
|
||||
versionName = "1.9.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
||||
@@ -130,11 +130,13 @@ fun DealListScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
)
|
||||
)
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
scrolledContainerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
modifier = Modifier.statusBarsPadding()
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
AnimatedVisibility(
|
||||
visible = showScrollToTop,
|
||||
@@ -148,7 +150,7 @@ fun DealListScreen(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
contentColor = MaterialTheme.colorScheme.onPrimary,
|
||||
shape = CircleShape,
|
||||
modifier = Modifier.padding(bottom = 80.dp) // 메뉴키에 가려지지 않도록 상단으로 이동
|
||||
modifier = Modifier.navigationBarsPadding()
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.KeyboardArrowUp,
|
||||
@@ -396,10 +398,10 @@ fun DealListScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// EdgeToEdge: 하단 네비게이션 바 공간 확보
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
// EdgeToEdge: 하단 네비게이션 바 공간 확보
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,22 +133,13 @@ class MainActivity : ComponentActivity() {
|
||||
* EdgeToEdge 설정 - One UI 7+ 대응
|
||||
*/
|
||||
private fun setupEdgeToEdge() {
|
||||
// WindowCompat을 사용한 설정
|
||||
// WindowCompat을 사용한 EdgeToEdge 설정
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
// statusBarColor와 navigationBarColor를 투명하게
|
||||
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
||||
window.navigationBarColor = android.graphics.Color.TRANSPARENT
|
||||
|
||||
// One UI 7+에서 시스템 바가 콘텐츠를 가리지 않도록 설정
|
||||
|
||||
// One UI 7+에서 시스템 바 인셋 처리
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
window.setDecorFitsSystemWindows(false)
|
||||
|
||||
// 시스템 바 인셋 처리
|
||||
ViewCompat.setOnApplyWindowInsetsListener(window.decorView.rootView) { view, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
|
||||
|
||||
view.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
@@ -159,29 +150,8 @@ class MainActivity : ComponentActivity() {
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||
)
|
||||
}
|
||||
|
||||
// 시스템 바 아이콘 색상 설정 (라이트/다크 모드)
|
||||
val decorView = window.decorView
|
||||
@Suppress("DEPRECATION")
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
window.insetsController?.let { controller ->
|
||||
// 상태바 아이콘 밝게 (다크 모드용)
|
||||
controller.setSystemBarsAppearance(
|
||||
0,
|
||||
android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
|
||||
)
|
||||
// 네비게이션바 아이콘 밝게 (다크 모드용)
|
||||
controller.setSystemBarsAppearance(
|
||||
0,
|
||||
android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility or
|
||||
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or
|
||||
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||
}
|
||||
|
||||
// 시스템 바 아이콘 색상 설정은 Theme.kt에서 처리
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
@@ -67,9 +67,7 @@ fun MainScreen(
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.windowInsetsPadding(WindowInsets.safeDrawing) // 시스템 바 패딩 적용
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
|
||||
@@ -17,109 +17,110 @@ import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.hotdeal.alarm.domain.model.SiteType
|
||||
|
||||
// Light Theme Colors
|
||||
private val LightPrimary = Color(0xFF1976D2)
|
||||
// ============================================
|
||||
// Material You Style - Premium Color Palette
|
||||
// ============================================
|
||||
|
||||
// Light Theme - Premium Palette
|
||||
private val LightPrimary = Color(0xFF0061A4)
|
||||
private val LightOnPrimary = Color(0xFFFFFFFF)
|
||||
private val LightPrimaryContainer = Color(0xFFD1E4FF)
|
||||
private val LightOnPrimaryContainer = Color(0xFF001D36)
|
||||
|
||||
private val LightSecondary = Color(0xFFFF9800)
|
||||
private val LightSecondary = Color(0xFF535F70)
|
||||
private val LightOnSecondary = Color(0xFFFFFFFF)
|
||||
private val LightSecondaryContainer = Color(0xFFFFE0B2)
|
||||
private val LightOnSecondaryContainer = Color(0xFF261800)
|
||||
private val LightSecondaryContainer = Color(0xFFD7E3F8)
|
||||
private val LightOnSecondaryContainer = Color(0xFF101C2B)
|
||||
|
||||
private val LightTertiary = Color(0xFF536DFE)
|
||||
private val LightTertiary = Color(0xFF6B5778)
|
||||
private val LightOnTertiary = Color(0xFFFFFFFF)
|
||||
private val LightTertiaryContainer = Color(0xFFF2DAFF)
|
||||
private val LightOnTertiaryContainer = Color(0xFF251431)
|
||||
|
||||
private val LightBackground = Color(0xFFFAFAFA)
|
||||
private val LightOnBackground = Color(0xFF1C1B1F)
|
||||
private val LightSurface = Color(0xFFFFFFFF)
|
||||
private val LightOnSurface = Color(0xFF1C1B1F)
|
||||
private val LightBackground = Color(0xFFFDFCFF)
|
||||
private val LightOnBackground = Color(0xFF1A1C1E)
|
||||
private val LightSurface = Color(0xFFFDFCFF)
|
||||
private val LightOnSurface = Color(0xFF1A1C1E)
|
||||
private val LightSurfaceVariant = Color(0xFFDFE2EB)
|
||||
private val LightOnSurfaceVariant = Color(0xFF43474E)
|
||||
|
||||
private val LightError = Color(0xFFD32F2F)
|
||||
private val LightError = Color(0xFFBA1A1A)
|
||||
private val LightOnError = Color(0xFFFFFFFF)
|
||||
private val LightErrorContainer = Color(0xFFFFDAD6)
|
||||
private val LightOnErrorContainer = Color(0xFF410002)
|
||||
|
||||
private val LightOutline = Color(0xFF79747E)
|
||||
private val LightOutlineVariant = Color(0xFFCAC4D0)
|
||||
private val LightOutline = Color(0xFF73777F)
|
||||
private val LightOutlineVariant = Color(0xFFC3C6CF)
|
||||
private val LightInverseSurface = Color(0xFF2F3033)
|
||||
private val LightInverseOnSurface = Color(0xFFF1F0F4)
|
||||
private val LightInversePrimary = Color(0xFF9ECAFF)
|
||||
private val LightSurfaceTint = Color(0xFF0061A4)
|
||||
|
||||
// Dark Theme Colors
|
||||
private val DarkPrimary = Color(0xFF90CAF9)
|
||||
// Dark Theme - Premium Palette
|
||||
private val DarkPrimary = Color(0xFF9ECAFF)
|
||||
private val DarkOnPrimary = Color(0xFF003258)
|
||||
private val DarkPrimaryContainer = Color(0xFF00497D)
|
||||
private val DarkOnPrimaryContainer = Color(0xFFD1E4FF)
|
||||
|
||||
private val DarkSecondary = Color(0xFFFFB74D)
|
||||
private val DarkOnSecondary = Color(0xFF442B00)
|
||||
private val DarkSecondaryContainer = Color(0xFF624000)
|
||||
private val DarkOnSecondaryContainer = Color(0xFFFFE0B2)
|
||||
private val DarkSecondary = Color(0xFFBBC7DB)
|
||||
private val DarkOnSecondary = Color(0xFF253140)
|
||||
private val DarkSecondaryContainer = Color(0xFF3B4858)
|
||||
private val DarkOnSecondaryContainer = Color(0xFFD7E3F8)
|
||||
|
||||
private val DarkTertiary = Color(0xFF8C9EFF)
|
||||
private val DarkOnTertiary = Color(0xFF001A3F)
|
||||
private val DarkTertiary = Color(0xFFD6BEE4)
|
||||
private val DarkOnTertiary = Color(0xFF3B2948)
|
||||
private val DarkTertiaryContainer = Color(0xFF523F5F)
|
||||
private val DarkOnTertiaryContainer = Color(0xFFF2DAFF)
|
||||
|
||||
private val DarkBackground = Color(0xFF121212)
|
||||
private val DarkOnBackground = Color(0xFFE0E0E0)
|
||||
private val DarkSurface = Color(0xFF1E1E1E)
|
||||
private val DarkOnSurface = Color(0xFFE0E0E0)
|
||||
private val DarkBackground = Color(0xFF1A1C1E)
|
||||
private val DarkOnBackground = Color(0xFFE2E2E6)
|
||||
private val DarkSurface = Color(0xFF1A1C1E)
|
||||
private val DarkOnSurface = Color(0xFFE2E2E6)
|
||||
private val DarkSurfaceVariant = Color(0xFF43474E)
|
||||
private val DarkOnSurfaceVariant = Color(0xFFC3C6CF)
|
||||
|
||||
private val DarkError = Color(0xFFCF6679)
|
||||
private val DarkOnError = Color(0xFF000000)
|
||||
private val DarkError = Color(0xFFFFB4AB)
|
||||
private val DarkOnError = Color(0xFF690005)
|
||||
private val DarkErrorContainer = Color(0xFF93000A)
|
||||
private val DarkOnErrorContainer = Color(0xFFFFDAD6)
|
||||
|
||||
private val DarkOutline = Color(0xFF938F99)
|
||||
private val DarkOutlineVariant = Color(0xFF49454F)
|
||||
private val DarkOutline = Color(0xFF8D9199)
|
||||
private val DarkOutlineVariant = Color(0xFF43474E)
|
||||
private val DarkInverseSurface = Color(0xFFE2E2E6)
|
||||
private val DarkInverseOnSurface = Color(0xFF2F3033)
|
||||
private val DarkInversePrimary = Color(0xFF0061A4)
|
||||
private val DarkSurfaceTint = Color(0xFF9ECAFF)
|
||||
|
||||
// =========================
|
||||
// index.html Inspired Colors
|
||||
// =========================
|
||||
// ============================================
|
||||
// Site Colors - Premium Tones
|
||||
// ============================================
|
||||
|
||||
// Dark Theme (index.html style)
|
||||
val IndexBgPrimary = Color(0xFF0f0f1a)
|
||||
val IndexBgSecondary = Color(0xFF1a1a2e)
|
||||
val IndexBgCard = Color(0xFF16162a)
|
||||
val IndexBgCardHover = Color(0xFF1e1e3a)
|
||||
val IndexBgInput = Color(0xFF252545)
|
||||
|
||||
val IndexTextPrimary = Color(0xFFffffff)
|
||||
val IndexTextSecondary = Color(0xFFa0a0b8)
|
||||
val IndexTextMuted = Color(0xFF6b6b8a)
|
||||
|
||||
val IndexAccentPrimary = Color(0xFF6366f1)
|
||||
val IndexAccentSecondary = Color(0xFF8b5cf6)
|
||||
|
||||
val IndexHotBadgeBg = Color(0x26EF4444) // rgba(239, 68, 68, 0.15)
|
||||
val IndexHotBadgeText = Color(0xFFef4444)
|
||||
|
||||
val IndexBoardBadgeBg = Color(0x26818CF8) // rgba(129, 140, 248, 0.15)
|
||||
val IndexBoardBadgeText = Color(0xFF818cf8)
|
||||
|
||||
// Light Theme (index.html style)
|
||||
val IndexLightBgPrimary = Color(0xFFf8fafc)
|
||||
val IndexLightBgSecondary = Color(0xFFffffff)
|
||||
val IndexLightBgCard = Color(0xFFffffff)
|
||||
val IndexLightBgCardHover = Color(0xFFf1f5f9)
|
||||
val IndexLightBgInput = Color(0xFFf1f5f9)
|
||||
|
||||
val IndexLightTextPrimary = Color(0xFF0f172a)
|
||||
val IndexLightTextSecondary = Color(0xFF475569)
|
||||
val IndexLightTextMuted = Color(0xFF94a3b8)
|
||||
|
||||
val IndexLightAccentPrimary = Color(0xFF4f46e5)
|
||||
val IndexLightAccentSecondary = Color(0xFF7c3aed)
|
||||
|
||||
val IndexLightHotBadgeBg = Color(0x1ADC2626) // rgba(220, 38, 38, 0.1)
|
||||
val IndexLightHotBadgeText = Color(0xFFdc2626)
|
||||
|
||||
val IndexLightBoardBadgeBg = Color(0x1A4F46E5) // rgba(79, 70, 229, 0.1)
|
||||
val IndexLightBoardBadgeText = Color(0xFF4f46e5)
|
||||
|
||||
// Site Colors
|
||||
// 뽐뿌 - Premium Pink
|
||||
val PpomppuColor = Color(0xFFE91E63)
|
||||
val ClienColor = Color(0xFF4CAF50)
|
||||
val RuriwebColor = Color(0xFF2196F3)
|
||||
val CoolenjoyColor = Color(0xFFFF5722)
|
||||
val PpomppuColorLight = Color(0xFFFCE4EC)
|
||||
val PpomppuColorDark = Color(0xFFC2185B)
|
||||
|
||||
// 클리앙 - Premium Green
|
||||
val ClienColor = Color(0xFF2E7D32)
|
||||
val ClienColorLight = Color(0xFFE8F5E9)
|
||||
val ClienColorDark = Color(0xFF1B5E20)
|
||||
|
||||
// 루리웹 - Premium Blue
|
||||
val RuriwebColor = Color(0xFF1565C0)
|
||||
val RuriwebColorLight = Color(0xFFE3F2FD)
|
||||
val RuriwebColorDark = Color(0xFF0D47A1)
|
||||
|
||||
// 쿨엔조이 - Premium Orange
|
||||
val CoolenjoyColor = Color(0xFFEF6C00)
|
||||
val CoolenjoyColorLight = Color(0xFFFFF3E0)
|
||||
val CoolenjoyColorDark = Color(0xFFE65100)
|
||||
|
||||
// Keyword Match - Light Red Theme
|
||||
val KeywordMatchColor = Color(0xFFE53935)
|
||||
val KeywordMatchColorLight = Color(0xFFFFEBEE)
|
||||
|
||||
// Favorite - Premium Red
|
||||
val FavoriteColor = Color(0xFFE53935)
|
||||
|
||||
/**
|
||||
* 사이트별 색상 가져오기
|
||||
@@ -134,6 +135,36 @@ fun getSiteColor(siteType: SiteType?): Color {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 사이트별 라이트 배경색 가져오기
|
||||
*/
|
||||
fun getSiteColorLight(siteType: SiteType?): Color {
|
||||
return when (siteType) {
|
||||
SiteType.PPOMPPU -> PpomppuColorLight
|
||||
SiteType.CLIEN -> ClienColorLight
|
||||
SiteType.RURIWEB -> RuriwebColorLight
|
||||
SiteType.COOLENJOY -> CoolenjoyColorLight
|
||||
null -> Color.LightGray.copy(alpha = 0.3f)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 사이트별 다크 배경색 가져오기
|
||||
*/
|
||||
fun getSiteColorDark(siteType: SiteType?): Color {
|
||||
return when (siteType) {
|
||||
SiteType.PPOMPPU -> PpomppuColorDark
|
||||
SiteType.CLIEN -> ClienColorDark
|
||||
SiteType.RURIWEB -> RuriwebColorDark
|
||||
SiteType.COOLENJOY -> CoolenjoyColorDark
|
||||
null -> Color.DarkGray
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Color Schemes
|
||||
// ============================================
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = LightPrimary,
|
||||
onPrimary = LightOnPrimary,
|
||||
@@ -145,16 +176,24 @@ private val LightColorScheme = lightColorScheme(
|
||||
onSecondaryContainer = LightOnSecondaryContainer,
|
||||
tertiary = LightTertiary,
|
||||
onTertiary = LightOnTertiary,
|
||||
tertiaryContainer = LightTertiaryContainer,
|
||||
onTertiaryContainer = LightOnTertiaryContainer,
|
||||
background = LightBackground,
|
||||
onBackground = LightOnBackground,
|
||||
surface = LightSurface,
|
||||
onSurface = LightOnSurface,
|
||||
surfaceVariant = LightSurfaceVariant,
|
||||
onSurfaceVariant = LightOnSurfaceVariant,
|
||||
error = LightError,
|
||||
onError = LightOnError,
|
||||
errorContainer = LightErrorContainer,
|
||||
onErrorContainer = LightOnErrorContainer,
|
||||
outline = LightOutline,
|
||||
outlineVariant = LightOutlineVariant
|
||||
outlineVariant = LightOutlineVariant,
|
||||
inverseSurface = LightInverseSurface,
|
||||
inverseOnSurface = LightInverseOnSurface,
|
||||
inversePrimary = LightInversePrimary,
|
||||
surfaceTint = LightSurfaceTint
|
||||
)
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
@@ -168,16 +207,24 @@ private val DarkColorScheme = darkColorScheme(
|
||||
onSecondaryContainer = DarkOnSecondaryContainer,
|
||||
tertiary = DarkTertiary,
|
||||
onTertiary = DarkOnTertiary,
|
||||
tertiaryContainer = DarkTertiaryContainer,
|
||||
onTertiaryContainer = DarkOnTertiaryContainer,
|
||||
background = DarkBackground,
|
||||
onBackground = DarkOnBackground,
|
||||
surface = DarkSurface,
|
||||
onSurface = DarkOnSurface,
|
||||
surfaceVariant = DarkSurfaceVariant,
|
||||
onSurfaceVariant = DarkOnSurfaceVariant,
|
||||
error = DarkError,
|
||||
onError = DarkOnError,
|
||||
errorContainer = DarkErrorContainer,
|
||||
onErrorContainer = DarkOnErrorContainer,
|
||||
outline = DarkOutline,
|
||||
outlineVariant = DarkOutlineVariant
|
||||
outlineVariant = DarkOutlineVariant,
|
||||
inverseSurface = DarkInverseSurface,
|
||||
inverseOnSurface = DarkInverseOnSurface,
|
||||
inversePrimary = DarkInversePrimary,
|
||||
surfaceTint = DarkSurfaceTint
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -197,19 +244,19 @@ fun HotDealTheme(
|
||||
|
||||
val view = LocalView.current
|
||||
if (!view.isInEditMode) {
|
||||
SideEffect {
|
||||
val window = (view.context as Activity).window
|
||||
// Edge-to-edge: 투명한 상태바
|
||||
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
||||
window.navigationBarColor = android.graphics.Color.TRANSPARENT
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = !darkTheme
|
||||
}
|
||||
SideEffect {
|
||||
val window = (view.context as Activity).window
|
||||
// 시스템 바 색상을 앱 배경색과 일치시켜 이질감 제거
|
||||
window.statusBarColor = colorScheme.surface.toArgb()
|
||||
window.navigationBarColor = colorScheme.surface.toArgb()
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = !darkTheme
|
||||
}
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = AppTypography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = AppTypography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
12
version.json
12
version.json
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"version": "1.6.0",
|
||||
"versionCode": 12,
|
||||
"version": "1.9.0",
|
||||
"versionCode": 15,
|
||||
"minSdk": 31,
|
||||
"targetSdk": 35,
|
||||
"forceUpdate": false,
|
||||
"updateUrl": "https://git.webpluss.net/attachments/0482dc08-5216-4223-beda-2887501578d8",
|
||||
"changelog": [
|
||||
"Pull to Refresh 기능 추가 (아래로 당겨서 새로고침)",
|
||||
"EdgeToEdge 개선 (투명 상태바/네비게이션바)",
|
||||
"출처를 알 수 없는 앱 설치 권한 추가",
|
||||
"WindowInsets 처리 개선"
|
||||
"EdgeToEdge 색상 개선 - 시스템 바가 앱 테마와 일치",
|
||||
"화면 공간 최적화 - 불필요한 패딩 제거",
|
||||
"TopAppBar가 시스템 바 영역까지 확장",
|
||||
"하단 네비게이션 영역 패딩 최적화"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user