Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

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

Billcorea 2025. 12. 11. 15:57
반응형

 

🦾 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)

반응형