Jetpack Compose

[Jetpack Compose] 컴포즈 Codelab 기초 따라하기 - 1

베르_최성훈 2023. 12. 19. 20:46

 

Jetpack Compose 를 시작하면서 코드랩을 따라하면서 작성한 글입니다. 파란색 글씨는 개인적인 생각입니다.

 

https://developer.android.com/codelabs/jetpack-compose-basics?hl=ko#0

Compose 시작하기

Composable function 은 @Composable 어노테이션이 달린 함수이다.

그럼 이 함수 내부에서 다른 @Composable 함수를 호출할 수 있다. 

 

 

Text 는 라이브러리에서 제공하는 컴포저블 함수이다. 이 함수를 내부에서 호출한 Greeting 은 컴포저블 어노테이션이 붙은 컴포저블 함수인 것이다. Greeting 함수는 name 문자열을 출력한다.

 

Compose 를 사용해도 Activity 가 Android 앱의 진입점으로 유지된다. setContent 에서 레이아웃을 정의하는데 기존 뷰 시스템의 XML 파일 대신 이 함수에서 컴포저블 함수를 호출하면 된다.

 

 

- Theme : 패키지 이름과 동일하게 만들어져있는 ComposeCodelabFirstTheme 함수가 있는데 이는 컴포저블 함수의 스타일을 지정하는 방법이다.

 

- Preview : AndroidStudio 미리보기를 사용하려면 @Preview 주석으로 표시하고 프로젝트를 빌드하면 된다. 동일한 파일에 미리보기를 여러 개 만들고 이름을 지정할 수도 있다. 

 

Preview 와 실제 보여지는 화면이 달라질 수 있구나.. 이렇게 설계된 의도가 무엇일까? 

Composable 의 장점을 살리기 위해서라고 생각한다. 컴포넌트를 각각 만들고 미리보고 조립하고 하기 위해서겠지?

 

그러면 실제 화면을 구성할때 미리보기와 실제 화면 중복이 필요한가...? 

그 의문은 아직 풀리지 않으니 계속 따라가보자.

 

 

 

UI 조정

 

이제 Greeting 에 다른 배경 색상을 설정해보자. Surface 로 래핑하면 된다.

 

배경 색깔만 바꿨는데 글자 색깔이 같이 흰색으로 바꼈다.. 뭐지?

다 비슷하게 생각하는지 코드랩에서 친절히 설명해놨다.

 

따로 정의하지 않았지만 Surface 같은 Material 구성요소는 foundation 의 다른 기본 구성 요소를 기반으로 더 나은 환경을 만들도록 빌드된다.

 

Surface 는 배경이 primary 색상으로 설정될 때 모든 텍스트가 onPrimary 색상을 사용해야한다고 인식힌다.

 

Modifier

modifier 를 사용해 UI 요소가 배치되고 표시되고 동작하는 방식을 정의할 수 있다.

 

 

Composable 재사용

구성요소가 많아지면 중첩 레벨이 더 많아진다. 함수가 커지면 가독성에 영향을 줄 수 있으니 중복되는 것들은 분리해 라이브러리를 만들고 독립적으로 수정해 사용하자.

 

함수는 기본적으로 빈 modifier 가 할당되는 modifier 매개변수를 포함하는 것이 좋다. 매개변수로 modifier 를 전달해 외부에서 레이아웃 웃을 조작할 수 있게 만든다.

 

열과 행 만들기

 

 

위는 Column, Row, Box 는 세가지 기본 표준 레이아웃 요소이다. 

 

Greeting 을 변경해 Column 을 만들어보자.

 

- Preview

 

Hello 와 name Text 를 새로로 배치하기위해 Column block 안에 순서대로 배치했다. 버튼과 텍스트는 반대로 가로로 배치해야하므로 Row 함수 블럭 안에 Column 과 ElevtedButton 을 추가했다.

 

다음으로 이 Greeting 을 목록으로 만들어보자

 

 

names 를 전달하면 개수만큼 목록을 그린다.

 

 

여기까지 하면 리사이클러뷰, 리스트뷰 처럼 스크롤이 될 줄 알았는데 스크롤은 되지 않는다. 단순히 세로로 배치한 것이다.

챕터 이름중에 목록에 애니메이션 적용이 있는거 보니 조금만 더 기다려보자..

 

Compose 에서의 상태

화면에 상호작용을 추가할 수 있다. 만들어 놓은 정적 레이아웃에 버튼을 클릭하면 상세 보기가 나오도록 펼쳐지고 다시 클릭하면 접히게 만들어보자.

 

현제 항목이 펼쳐진 상태인지 접힌 상태인지 저장할 필요가 있다. 이 값의 논리적 위치는 Greeting 컴포저블에 있다.

 

 

이렇게 변수를 추가하고 상태에 따라 클릭했을 때  접기, 펼치기 글씨가 바뀌게 만들었다. 그러나 이는 동작하지 않는다. 

 

컴포즈에서 이 값의 변화를 상태 변경으로 감지하지 않기 때문이다!!

 

Compose 앱은 Composable 함수를 호출해 데이터를 UI 로 변환한다. 데이터 변경시 새 데이터로 이 함수를 다시 실행해 업데이트한 UI 를 재구성한다. 이를 리컴포지션이라고 한다. 또한, 데이터가 변경된 구성요소만 다시 구성하고 영향을 받지 않는 구성요소는 다시 구성하지 않고 건너뛴다.

 

위에서 expended 변수가 변경되었을 때 리컴포지션 이 트리거되지 않는 이유는 이 변수를 컴포즈에서 추적하지 않기 때문이다. 또한 Greeting 이 호출될 때마다 false 로 초기화된다.

 

컴포저블 함수에 내부 상태를 추가하려면 mutableStateOf 함수를 사용해야한다.

하지만 이 함수만 사용하면 리컴포지션간 상태를 유지할 수 없다. 여러 리컴포지션 간에 상태를 유지하려면 remember 를 사용해 상태를 기억해야한다.

 

 

StateFlow, LiveData  처럼 구독하는 형태로 보인다

 

remember 를 사용했기 때문에 상태가 재설정되지 않으며 내부 상태는 클래스의 비공개 변수가 된다.

 

 

 

상태가 저장되어 이제 접기 펼치기 텍스트 변경이 가능해졌다!

 

 

이제 실제로 항목을 펼쳐보자

 

 

 

extraPadding 변수를 지정해주고 expended 변수의 상태에 따라 Padding (bottom) 이 변경되도록 하였다.

 

그럼 이렇게 접고 펼치기가 가능해졌다.

 

내용이 많아서 상태 호이스팅 이후는 다음 글로 알아보자!

 

마무리하며

컴포즈 너무 재밌는데요?