Today's

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

모바일 앱(안드로이드)

🕹️ Android | Wear Compose UI 레이아웃 정리와 중앙정렬, 문자열 리소스화

Billcorea 2025. 12. 17. 15:52
반응형

 

🕹️ Android | Wear Compose UI 레이아웃 정리와 중앙정렬, 문자열 리소스화

앱 구성중

 

개요 (Intro)

  • 오늘의 목표 / 배경: Wear OS 앱의 메인 화면 Compose 레이아웃을 모듈화하고 가독성을 높이며, 텍스트 중앙정렬과 문자열 리소스화를 적용
  • 어떤 문제를 해결하려 했는지: 거대한 단일 컴포저블 내부 UI가 난해하고, 일부 하드코딩 텍스트/정렬 불일치가 존재
  • 사용한 기술 스택: Kotlin, Jetpack Compose for Wear, Hilt, Coroutines
📅 날짜: 2025.12.17
🎯 목표: Compose UI 분리(refactor) + 중앙정렬 + 문자열 리소스화 + 불필요 섹션 제거
🧰 기술: Kotlin, Android Studio, Compose, MVVM-ish, Hilt

문제 정의 (Problem / Motivation)

  • 메인 UI가 하나의 거대한 함수에 몰려 있어 읽기/수정이 어려움
  • 일부 텍스트가 하드코딩되어 국제화/재사용성에 제약
  • 센터 정렬이 필요한 텍스트들이 좌측정렬로 되어 UI 일관성이 떨어짐
  • Wear OS에서 의미가 약한 배터리 최적화 안내/버튼 섹션 존재
// 예시 (정리 이전): 단일 컴포저블 안에 다양한 UI가 혼재해 가독성 저하
@Composable
fun WearApp() {
    // ... 상태/권한/서비스 로직
    Scaffold {
        ScalingLazyColumn {
            // 권한, 상태, 위치, PDR, 배터리 섹션이 모두 item 블록으로 길게 나열됨
        }
    }
}

해결 과정 (How I Solved It)

  • UI를 작은 컴포저블들로 분리: PermissionSection, StatusSection, LocationSection, PdrSection
  • 텍스트 중앙정렬: 모든 텍스트 컴포넌트에 Modifier.fillMaxWidth() + TextAlign.Center 적용
  • 문자열 리소스화: 하드코딩된 한글("전송 임계값=")을 strings.xml로 이전
  • 불필요한 배터리 최적화 섹션 제거
// 파일: MainActivity.kt — 초보자도 이해하기 쉬운 주석 포함 예시
// 1) 가운데 정렬을 위한 import
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.text.style.TextAlign

@Composable
fun StatusSection(
    syncStatusText: String,
    syncStatusColor: Color,
    steps: Long,
    lastDelta: Long,
    stepThreshold: Long,
    headingRad: Double,
    lastPayload: StepPayload?,
    altitude: Double?,
    unit: String
) {
    // Column의 수평 정렬은 Center로 유지하되,
    // 각 Text를 화면 너비만큼 확장하고(Text가 가로폭을 차지),
    // TextAlign.Center로 내용을 중앙에 배치
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(
            text = syncStatusText,
            color = syncStatusColor,
            style = MaterialTheme.typography.bodySmall,
            modifier = Modifier.fillMaxWidth(), // 전체 너비 사용
            textAlign = TextAlign.Center        // 텍스트 중앙 정렬
        )
        Spacer(Modifier.height(4.dp))
        Text(
            text = stringResource(R.string.steps_label) + ": " + steps + " (Δ " + lastDelta + ")",
            style = MaterialTheme.typography.bodySmall,
            modifier = Modifier.fillMaxWidth(),
            textAlign = TextAlign.Center
        )
        Text(
            text = stringResource(R.string.step_threshold_label) + stepThreshold,
            style = MaterialTheme.typography.bodySmall,
            modifier = Modifier.fillMaxWidth(),
            textAlign = TextAlign.Center
        )
        Text(
            text = String.format(
                java.util.Locale.US,
                stringResource(R.string.heading_label) + ": %.0f°",
                Math.toDegrees(headingRad)
            ),
            style = MaterialTheme.typography.bodySmall,
            modifier = Modifier.fillMaxWidth(),
            textAlign = TextAlign.Center
        )
    }
}


전송 임계값=
// 파일: MainActivity.kt — 배터리 최적화 섹션 제거 예시
// 기존: BatteryOptimizationSection(...) 사용 및 관련 PositionIndicator 주변 조건부 렌더링
// 변경: 해당 섹션/조건 로직 삭제로 UI 단순화

결과 (Result)

  • UI가 섹션별 컴포저블로 분리되어 가독성 및 유지보수성 향상
  • 텍스트 중앙정렬로 일관된 시각 경험 제공
  • 문자열 리소스화로 국제화/재사용성 개선
  • 불필요한 배터리 최적화 UI 제거로 사용자 혼란 감소
✅ Compose 아이템들이 깔끔하게 모듈화됨
🎯 텍스트 중앙정렬 적용으로 UI 일관성 확보
🧩 문자열 리소스 관리로 다국어 및 유지보수 용이

느낀 점 / 회고 (Reflection)

  • Wear Compose에서도 작은 컴포저블로 나누는 것이 가장 큰 생산성 향상을 가져온다
  • 하드코딩 텍스트는 사소해 보여도 국제화/테스트/일관성 측면에서 리소스화가 중요
  • 기기 특성(Wear OS)을 고려한 UI/설정 항목은 실제 동작 가능 여부를 검증 후 제공해야 한다

참고자료 (References)

반응형