[Jetpack Compose] 컴포즈의 기본 개념

mi-fasol·2023년 1월 13일
0

Compose

목록 보기
1/6

해당 게시물은 과거에 작성한 블로그 내용을 옮겨 온 것으로, 가독성이 떨어지고 내용이 부정확할 수 있습니다.

Compose란?

  • 선언형 프로그래밍을 사용하여 UI를 제작하는 개발 툴
  • 기존보다 적은 코드로 네이티브 UI 구축 가능
  • 직관적이고 강력하며 개발에 가속화 가능
  • Views보다 더 현대적인 툴키트가 필요해짐에 따라 개발

Views와 비교했을 때 Compose의 장점

  • Views: XML에 UI를 선언

    즉, 데이터 변경 시 데이터 동기화와 UI 업데이트 필수적

  • Compose: 특정 상태에 맞춰 UI를 새로 생성
    • 변경되지 않은 요소에 대한 작업을 건너뜀
    • UI의 구성 요소는 그저 구성 가능한 주석이 달린 함수
      ⇒ 빠르고 쉽게 구성 가능
    • 재사용 가능한 요소로 구성된 라이브러리로 UI를 나누는 것을 권장
    • Compose는 매개변수를 받을 수 있고, 받아야 함
    • 데이터를 함수의 매개변수로 받은 후 UI 전달
    • UI가 동기화 상태에서 벗어나지 않음

Composable 함수의 예시

  • 체크 박스 예시
@Composable
fun MessageList(messages: List<String>){
   Column {
       Checkbox(
           checked = false	// 체크박스는 unchecked가 default
       )
       ...
    }
}
  • 다른 예시
@Composable
fun MessageList(messages: List<String>) {
   Column {
   	   // 체크 선택 여부를 결정하는 로컬 변수
       var selectAll: Boolean = ...	
       Checkbox(
           checked = selectAll,
           // 체크박스 선택 시 onCheckChange 이벤트 제공
           onCheckChange = { checked ->
               selectAll = checked
           }
        )
        ...
     }
}
  • 처음에는 직관적이지 못한 코드라고 생각할 수 있지만 이것이 선언적 UI의 핵심 개념
    • 위와 같은 코드를 사용해야 상태를 읽을 때 체크박스를 다시 받아옴

선언적 UI의 핵심

  • 특정 상태에서 UI의 형태를 완전히 설명
  • 상태가 바뀌면 프레임워크에서 UI 업데이트 처리
  • Compose는 단방향 데이터 플로우를 따르는 아키텍처와 잘 맞음
    • 뷰모델이 화면 상태의 단일 스트림을 노출하면 Compose UI에서 관찰
    • 그 후 각 구성요소의 매개변수로 전달
    • 각 구성요소는 필요한 상태만 수신하므로 데이터 변경 시에만 업데이트
    • 전체적 화면 상태를 추론하고 오류를 낮추기 쉬움

Compose의 개념 - UI 툴키트

  • Jeckpack Compose는 머터리얼 디자인 구성요소, 테마 시스템 구현
    • 또한 애플리케이션을 어셈블하는 데 필요한 구성요소 제공
    • Buttons, Cards, FABs, AppBars 등
  • 모든 구성 요소를 브랜드에 맞게 커스터마이징 할 수도 있음
  • Compose는 간단하지만 강력한 새 레이아웃 시스템을 제공
    • 행과 열 기반
    • LinearLayout과 비슷한 개념
  • Compose 레이아웃 모델은 여러 척도를 전달할 수 없음
    • 중첩된 레이아웃에 적합

Compose의 특징

  • 테스트와 접근성이 1급 객체
  • 테스트
    • 테스트 기능을 극대화하는 전용 테스트 아티팩트 제공
    • 독립적으로 컴포저블을 테스트하는 간편한 API 제공
  • 접근성
    • UI에 병령 트리를 생성하는 시맨틱 시스템 기반
  • 필요에 따라 점진적으로 도입 가능
    • 화면의 작은 요소부터 시작해서 UI의 큰 부분이나 화면 전체 교체 가능
    • Views에 Compose를 포함시킬 수도 있고 Compose에 Views를 호스팅 할 수도 있음

Recomposing

  • Recomposing: 상태가 바뀌었을 때 함수를 실행하면 새로운 UI가 생성되는 것
    • Compopse 컴파일러는 어느 컴포저블이 상태를 읽는지 추적 후 상태가 바뀌면 자동으로 재실행
    • 입력이 변경된 컴포저블만 다시 실행하고 나머지는 건너뛰어 효율적
    • 각 컴포저블은 변경 불가
      ⇒ 컴포저블 참조, 쿼리, 내용 업데이트 불가
      ⇒ 정보 입력 시 모두 매개변수로만 전달
      ⇒ 컴포저블이 고정되었다는 뜻은 아님

최종 예시

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.img),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
        )

        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            Text(text = msg.body)
        }
    }
}


@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard(
        msg = Message("Colleague", "Hey")
    )
}
  • 결과물
profile
정위블

0개의 댓글