pile·
모바일·딜리셔스딜리셔스·

Android Jetpack Compose 한 번 써봤습니다

딜리셔스 안드로이드 개발자가 신상캐시 송금 서비스에 Jetpack Compose 를 시범 적용한 경험담이다. 대부분은 컨버팅이 쉬웠지만 TextField 의 포커스 처리와 천 단위 콤마, 그리고 무한 스크롤에서 커스텀이 많이 필요했던 지점을 코드와 함께 남긴다.

핵심 포인트
  • 기존에는 xml layout 으로 화면을 그렸는데, Compose 를 쓰면 Kotlin 만으로 개발되고 뷰를 직접 조작하며 생기던 번거로움과 버그 위험이 줄어든다.
  • 기존 코드와 호환돼 전부 바꾸지 않고 점진적으로 적용할 수 있다는 점이 시도의 계기가 됐다.
  • 손이 갔던 부분: Button·TextField 같은 Composable 에 안드로이드가 미리 정해 둔 padding·elevation 기본값이 있어 디자인 시안에 맞추려면 재조정이 필요했다.
  • TextField 는 Composable 함수라 특정 객체인지 판단할 수 없어, 기존 `dispatchTouchEvent` 로 포커스를 해제하던 방식 대신 포커싱 여부 변수를 따로 둬야 했다.
  • 천 단위 콤마는 `onValueChange` 로 처리하려다 커서 위치 버그를 만났고, `VisualTransformation` 으로 해결했다.
상세 정리
  • 예제는 Compose 1.0.5 기준이며, 안드로이드 팀 스터디를 계기로 몇몇 동료가 새 기능 개발에 시범 적용했다.
  • 구글이 내세우는 이유(코드 감소, 직관적, 빠른 개발, 강력한 성능)를 인용한 뒤 "개발자들이 편하게 UI 개발하라고 만든 툴킷" 으로 요약한다.
  • 기본 Composable 부터 복잡도 높은 것까지 대부분의 기능이 미리 구현돼 있어 코드가 간결했고 컨버팅에 큰 어려움이 없었다고 평가한다.
  • 콤마 처리 1차 시도: ViewModel 에 LiveData 변수를 두고 observe 하며 TextField 값을 관리하고, keyboardType 을 Number 로 준 뒤 파싱한 값을 콤마 포함 문자열로 업데이트했다.
  • 붙여넣기 등으로 유효하지 않은 Long 값이 들어오면 0L 로 초기화되도록 확장 함수를 만들어 썼다.
  • 버그의 정체: 커서 위치를 계산할 때 콤마가 고려되지 않았다. 그런데 EditText 의 `setSelection` 을 대체할 함수를 Compose 에서 찾지 못했다.
  • 해결: `VisualTransformation` 은 화면에 보이는 출력 값만 바꾸는 인터페이스로 비밀번호 마스킹, 천 단위 콤마, 전화번호 포맷팅에 자주 쓰인다. 텍스트 추가·삭제 시 커서 위치를 얼마나 보정할지 처리하는 클래스를 직접 만들었다.
  • 구조 변경: ViewModel 은 콤마를 뺀 숫자만 들고 있게 하고, 화면에만 콤마가 보이도록 분리했다.
  • 무한 스크롤: 첫 진입 시에는 전체 화면 로딩으로, 두 번째 로딩부터는 이미 불러온 아이템 아래에 인디케이터나 실패 메시지를 붙이는 예외 처리를 그대로 유지했다.
  • 로딩 상태를 판단할 enum 을 만들고, 그 값에 따라 LazyColumn 안에서 그릴 Composable 을 분기했다. 상단 고정 Header 만 밖에 둔다.
  • 스크롤 감지는 `LazyListState` 로 한다. 스크롤을 관찰·제어하고 화면에 처음·마지막으로 보이는 아이템 인덱스를 얻을 수 있어, 관련 판단 로직을 확장 함수로 정리했다.
  • 스크롤이 바닥에 닿기 전에 미리 통신하도록 buffer(마지막 아이템으로부터 몇 개 남았을 때 로드할지)를 두고, 음수면 예외를 던지게 했다.
  • 총평 ①: 코드가 확실히 줄었다. layout 을 따로 그릴 필요가 없고 도형이나 selector 를 위해 여러 xml 을 만들던 작업이 몇 줄로 처리된다.
  • 총평 ②: ViewModel 과의 상호 사용에 최적화돼 있어 예전처럼 View 와 Data 가 따로 노는 일이 거의 없을 것으로 본다.
  • 주의점: 아직 정식 출시되지 않은 Composable 이 많아 형태가 바뀔 수 있고, 기존 위젯과 생김새·동작이 달라 이전과 같은 UX 를 주려면 주의해 커스텀해야 한다.
왜 읽나Compose 도입을 검토하는 안드로이드 개발자에게, 쉬운 부분과 실제로 시간이 걸리는 부분(입력 필드·무한 스크롤)을 코드 수준으로 구분해 준다.
딜리셔스
딜리셔스 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 모바일·당근당근 테크블로그·

    웹뷰 다음의 레일을 깔다: 당근이 Lynx를 선택한 이유

    당근 프론트엔드코어팀이 WebView 기반 화면의 첫 프레임 렌더링 문제를 해결하기 위해 Lynx를 도입한 기록이다. 레퍼런스가 거의 없는 기술을 코드베이스 직접 분석으로 검증한 뒤 프로덕션에 적용했고, 1.9백만 사용자 A/B에서 Android 18%, iOS 37%의 첫 프레임 단축을 달성했다.

    요약 이어보기
    #cross-platform#webview#mobile-performance+2
  2. 모바일·토스 SLASH토스 SLASH·

    토스의 디바이스 팜 만들기

    토스가 각 팀이 각자 운영하던 작은 디바이스 팜을 하나의 중앙 플랫폼 '네뷸라(Nebula)'로 통합한 과정을 다룬다. Appium 대신 자체 드라이버를 개발해 클릭 13.5배, 텍스트 입력 10배의 성능을 달성했고, Android와 iOS 미러링도 직접 내재화해 실기기 원격 조작과 화면 실시간 공유를 동시에 가능하게 만들었다. 현재 100대를 넘어 수백 대를 향해 24시간 가동 중이다.

    요약 이어보기
    #android#ios#appium+2