🦾 Android | 워치앱 빌드 오류 수정과 UI/국제화 개선 정리

개요 (Intro)
- 오늘의 목표 / 배경: 워치앱(MainActivity) 빌드 오류를 해결하고, 스크롤바/버튼 텍스트 레이아웃/국제화(strings.xml) 개선
- 어떤 문제를 해결하려 했는지: 미선언 변수(dayKey)로 인한 컴파일 오류, 텍스트 줄임 표시, 스크롤바 가시성, 하드코딩 문자열 정리
- 사용한 기술 스택: Kotlin, Jetpack Compose, Wear OS, Coroutine, Hilt
📅 날짜: 2025.12.11
🎯 목표: 워치앱 컴파일 오류 제거 + UI/국제화 개선
🧰 기술: Kotlin, Android Studio, Compose, Wearable APIs
문제 정의 (Problem / Motivation)
- 워치앱의
MainActivity.kt에서 Unresolved reference 'dayKey' 빌드 에러 발생 - 타일/메인 화면 일부 텍스트가 길어 줄임표(...)로 보이는 문제
- 스크롤바가 배경과 유사해 가시성이 떨어짐
- 하드코딩된 한글 문자열의 국제화(strings.xml) 필요
// 컴파일 에러 예시 (요약)
// e: MainActivity.kt: Unresolved reference 'dayKey'
// 자정 체크 로직에서 dayKey 상태가 정의되어 있지 않음
해결 과정 (How I Solved It)
- dayKey 상태 추가: 자정 변경 감지를 위해
remember { mutableStateOf(...) }로 dayKey를 선언 - 스크롤바 색 개선: 배경색의 보색(Complementary color)로 스크롤바 트랙/썸을 그려 가시성 상승
- 텍스트 레이아웃 개선: 여백 조정 및 항목 분리로 줄임표 빈도 감소, 향후 Chip/버튼 폭/높이 조정 계획 반영
- 국제화: 화면에 보이는 주요 한글 문자열은
stringResource(...)로 대체하고 리소스로 이동(추가 정리 예정)
// 핵심 수정 예시: dayKey 상태 추가 및 자정 리셋 로직 유지
@Composable
fun WearApp() {
// ... 기존 상태들 ...
// 일자 키(자정 교체 감지용)
var dayKey by remember {
mutableStateOf(
java.time.ZonedDateTime.now()
.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
)
}
// 자정 변경 감지: 1분마다 체크하여 dayKey 달라지면 스텝/PDR 리셋
LaunchedEffect(Unit) {
while (true) {
val current = java.time.ZonedDateTime.now()
.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
if (current != dayKey) {
dayKey = current
// 스텝 리셋 및 PDR 리셋
passiveStepsManager.stop(); passiveStepsManager.start()
pdr.reset()
}
kotlinx.coroutines.delay(60_000L)
}
}
}
// 스크롤바 가시성 개선: 배경색 보색 사용
val animatedBg by animateColorAsState(targetValue = bgColor, animationSpec = tween(150))
val scrollbarColor = Color(1f - animatedBg.red, 1f - animatedBg.green, 1f - animatedBg.blue)
Canvas(modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 2.dp)
.height(100.dp)
.width(3.dp)) {
val contentHeight = scrollState.maxValue.toFloat() + size.height
if (contentHeight > size.height + 1f) {
val ratio = size.height / contentHeight
val thumbHeight = (size.height * ratio).coerceAtLeast(12f)
val scrollY = (scrollState.value / scrollState.maxValue.toFloat()).coerceIn(0f, 1f)
val thumbTop = (size.height - thumbHeight) * scrollY
drawRect(color = scrollbarColor.copy(alpha = 0.2f), size = size) // 트랙
drawRect(color = scrollbarColor, topLeft = Offset(0f, thumbTop), size = Size(size.width, thumbHeight)) // 썸
}
}
// 국제화 적용 예시: 하드코딩 제거
Text(stringResource(R.string.steps_label) + ": $steps (Δ $lastDelta)")
Text(stringResource(R.string.altitude_barometer_label) + ": $altText")
결과 (Result)
- 워치앱 컴파일 오류 해결 (dayKey 상태 추가)
- 스크롤바가 배경과 대비되어 가시성 향상
- 텍스트 줄임표 이슈 완화, 국제화 기반으로 문자열 관리 준비
✅ 워치앱이 정상 빌드/실행됨
📱 UI 가독성 개선, 유지보수성(국제화) 향상 기반 구축
느낀 점 / 회고 (Reflection)
- 작은 상태 누락(dayKey)도 앱의 핵심 흐름(자정 리셋)에 영향을 크게 줄 수 있음
- UI 색 대비는 접근성과 직결되므로 초기 단계부터 고려하는 게 중요
- 국제화는 나중에 몰아서 하기보다, 화면 작업과 함께 병행해야 리스크가 줄어듦
참고자료 (References)
반응형
'모바일 앱(안드로이드)' 카테고리의 다른 글
| 🔍 프로젝트 진단 | Health501 아키텍처 & 코드 품질 개선 로드맵 (1) | 2025.12.15 |
|---|---|
| 🧪 테스트 시나리오 | AiAutoSelector 단위 테스트 실패 → 가중치 조정 및 외부 설정 리팩터링 (1) | 2025.12.13 |
| 🐾 Android | Kalman vs EMA — 고도/센서 데이터 필터링 비교와 적용기 (2) | 2025.12.09 |
| 🧭 Android | 위치 수신·히스토리 저장 및 Vico 그래프 NaN 크래시 대응 (1) | 2025.12.07 |
| ⌚ Wear OS | 센서 수명주기·권한·동기화 연결로 기본 데이터 파이프 완성 (2) | 2025.12.05 |