반응형
전통적인 뷰 기반 접근 방식은 컴포넌트와 클래스에 중점을 뒀던 것에 비해
새로운 프레임워크는 선언적 접근 방식을 따른다.
안드로이드 뷰 시스템 살펴보기
- 기존 접근 방식
- 컴포넌트 트리를 정의하고 런타임에서 변경하는 것
- 레이아웃 파일은 계층구조(트리)를 정의
- 레이아웃 파일 인플레이팅
- 두가지 문제
- 변수를 초기화 하기 전에 접근하면 런타임에서 크래시
- 컴포넌트 개수가 많아지면 코드가 비대해짐
- 두 번째 문제를 해결하고자, 컴포넌트 참조를 계속 유지해야 하는 작업을 덜어주고자 구글은 뷰 바인딩 기능을 제공
- 두가지 문제
- 일반적인 UI 프레임워크를 명력적이라고 하는 이유
- UI는 XML파일로 정의
- UI는 런타임 단계에서 컴포넌트 트리로 인플레이트된다.
- UI를 변경하려면 연관된 모든 컴포넌트의 속성을 수정해야만 한다.
- UI 요소가 화면에서 보이지 않더라도 컴포넌트 트리의 요소로는 남아있다.
컴포넌트에서 컴포저블 함수로 이동
- 컴포넌트 계층 구조
- 전문적인 속성일 수록 다른 컴포넌트에 재사용할 가능성이 낮아진다.
- 모든 안드로이드 뷰는 클래스다
- 레이아웃 파일의 태그는 클래스를, 속성은 클래스의 멤버를 나타낸다
- inflate()는 객체 트리를 생성한다
- 객체 트리를 수정해 UI를 변경한다.
android.view.View는 모든 안드로이드 UI 요소의 최상위 요소가 된다.
- 컴포넌트 계층 구조의 한계
- 예) 버튼이 텍스트를 보여준다. 이미지를 보여주고 싶으면 이미지 버튼
- 둘다 보여주고 싶으면? 가까운 공통 부모는 View이다.
- 버튼의 모든 기능은 이미지 버튼에서 바로 사용할 수 없다.
- 이는 자바가 단일 상속 기반이기 때문
- 뷰는 패딩에 대해 알고 있지만 마진은 모른다. 마진은 뷰그룹이 알고 있다.
- 사용하고 싶으면 뷰그룹을 확장해야 한다. → 필요 유무와 관계없이 다른 모든기능을 상속하게 된다.
- 개별 기능을 분리할 수 없기 때문
- 예) 버튼이 텍스트를 보여준다. 이미지를 보여주고 싶으면 이미지 버튼
- 잿팩 컴포즈는 구성 요소끼리 조합하는 방식을 사용(플러터와 같음)
- 클래스 대신 컴포저블 함수를 사용
- 컴포저블 UI의 진입점은 컴포저블 함수다
- 거기서부터 다른 컴포저블 함수가 호출된다.
- 컴포저블 함수는 주로 content 매개변수를 전달 받는데, 이는 다른 컴포저블 함수다
- 호출 순서는 다른 UI요소와 비교해 UI요소가 위치할 곳을 제어한다.
레이아웃 파일은 초기 상태로 컴포넌트 트리를 정의하는 반면
컴포저블 UI는 항상 실제 데이터를 사용해 정의
- UI가 화면에 나타나기 전에 이를 설정하거나 준비할 필요가 없다는 것
동작 원리
- 컴포저블 함수는 항상 실제 값으로 호출
- 컴포즈 UI를 업데이트 하는 일련의 과정을 재구성이라 부름.
재구성
- UI의 일부인 컴포저블 함수가 업데이트돼야 할 때마다 자동으로 발생
- UI의 모습이나 행위에 영향을 주는 값 중 일부가 변경되는것이 해당
- 잿팩 컴포즈가 UI 변경이 필요하다고 판단되는 값을 전달한다면 컴포즈 런타임은 변경이 일어나면 재구성 방식을 사용해 UI 업데이트를 수행할 것이다.
- 시간이 지나면서 변경되는 값을 상태(State)라고 한다.
- mutableStateOf()를 사용하면 상태를 생성할 수 있다.
- 컴포저블 함수에서 상태를 참조하려면 함수에서 remember(기억) 해야 한다.
아키텍처 관점에서 설명
일반 적인 기능은 다음 사항을 포함
- 화면의 위치와 크기
- 배경과 같은 기본적인 시각적 측면
- 간단한 사용자 상호작용(클릭에 반응)
안드로이드 뷰 시스템은 클래스 기반이기 때문에 부모 메서드를 재정의해 기능을 변경하게 된다.
반면
컴포저블 함수는 공유되는 프로퍼티가 존재하지 않는다.
@Composable 어노테이션을 함수에 추가하는 것으로 함수를 인지하게 할 수 있다.
- 반환 타입을 명시하지 않는다는 점 외에 컴포저블 함수는 공통적인 부분이 거의 없는것 처럼 보인다.
- 그러나 아키텍처의 관점의 판단일지도 모른다.
클릭 동작에 반응
잿팩 컴포즈는 두가지 방식으로 클릭 이벤트 처리를 제공
1. 클릭 이벤트 처리를 필요로 하는 컴포저블 함수는 전용 onClick매개변수를 갖는다
@Composable
@Preview
fun ButtonDemo() {
Box {
Button(onClick = {
println("clicked")
}) {
Text("Click me!")
}
}
}
onClick이 필수
2. 변경자(modifier)로 수정할 수 있다.
modifier = Modifier.clickable { ...
UI 요소 크기 조절과 배치
- Box() 는 FrameLayout과 유사
- 박스 내부에서 위치는 contentAlignment로 제어
@Composable
@Preview
fun BoxDemo() {
Box(contentAlignment = Alignment.Center) {
Box(
modifier = Modifier
.size(width = 100.dp, height = 100.dp)
.background(Color.Green)
)
Text(
text = "Hello",
color = Color.Black,
modifier = Modifier.align(Alignment.Topstart)
)
}
}
- Modifier.fillMaxSize() : 컴포저블 함수를 가능한 한 크게 만들어줌.
변경자는 체이닝이 가능하다.
- 체이닝의 최상위는 Modifier 동반객체(companion object)
참조 : 젯팩 컴포즈로 개발하는 안드로이드 UI
반응형
'코틀린 & Java > 컴포즈 Compose' 카테고리의 다른 글
컴포즈(compose) 앱 스타일링 (0) | 2024.01.29 |
---|---|
컴포즈(compose) 컴포저블 함수 상태 관리 (0) | 2023.09.05 |
컴포즈(Compose) UI 요소 배치 (0) | 2023.08.23 |
컴포즈(Compose) 컴포즈 핵심 원칙 자세히 알아보기 (0) | 2023.08.16 |
컴포즈(Compose) 앱 빌드 (0) | 2023.08.16 |