2024. 7. 30. 15:34ㆍ[개발]/Kotlin 활용 앱 개발
# Compose의 개념
- Jetpack Compose : 안드로이드 UI를 선언적으로 구축하는 도구
- 기존의 View 방식(XML + kotlin)에서 발생하는 다양한 문제에 대응
# View 방식의 문제점
1) UI 개발에서의 높은 복잡성
2) 상속 문제
# Compose의 해결 방식
- 선언적인 UI 작성 방식
- 상속 대신 합성(머지) 채택 / 유지보수성 향상
# 선언형(Declarative) UI
- "어떻게 보여줄까?" 가 아니라 "무엇을 보여줄까"를 기술함
- 구현 세부 사항은 시스템이나 프레임워크에 위임
- Composable 함수라는 독립적 단위로 UI 구성 / 직관적 + 재사용성 高
# ViewModel 활용
- Compose의 선언형 접근 방식에서 위젯은 비교적 Stateless 상태로, setter/getter(setText(), getText() 등) 함수를 노출 X
- 위젯은 객체로 노출되지 않고, 동일한 Composable 함수를 다른 인수로 호출해 UI 업데이트
- ViewModel과 같은 아키텍쳐 패턴에 쉽게 State를 제공할 수 있음
# 데이터 흐름
- 최상위 구성 가능한 함수에 데이터 제공
- 함수를 데이터를 사용해 다른 Composable을 호출, UI 형성
- 적절한 데이터를 해당 Composablem, 계층 구조 아래로 전달
# 이벤트 흐름
- 사용자가 UI 요소와 상호작용함에 따라 이벤트 발생 / 앱 로직이 이벤트에 응답
- Composeable 함수가 필요한 경우 새 매개변수를 사용해 자동으로 다시 호출
(참고: https://developer.android.com/develop/ui/compose/mental-model?hl=ko)
# MVVM 패턴 활용 - 개념
1) Model (Data Layer)
- Viewmodel에서 요청한 데이터 처리, 반환
- Local DB(SQLite, Room), 네트워크 통신(Retrofit) 이용
2) View(UI Layer)
- 액티비티, 프래그먼트가 View 역할 담당
- 사용자의 액션을 받음
- ViewModel의 데이터를 관찰해 UI 갱신
- 사용자의 액션을 감지하고 데이터 변화를 통해 UI 갱신 처리
3) ViewModel(UI Layer)
- 사용자의 액션, 라이프사이클에 의해 View에서 요청한 데이터, 비즈니스 로직 처리
- Model에 요청한 데이터를 받음
# MVVM 패턴 활용 - UI Layer
# UI State 관리
package com.example.mvvmcompose
import android.os.Bundle
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.flowWithLifecycle
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.collectLatest
// UI Layer - MvvmActivity
class MvvmActivity : AppCompatActivity() {
// viewModel 선언
private val viewModel : MvvmViewmodel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// 화면이 생성되자마자 Viewmodel 초기화 실행
initViewModel()
// viewModel에서는 uiState의 데이터를 받아옴
viewModel.requestBoard()
}
// 화면 생성과 동시에 뷰모델을 초기화하는 함수를 정의
private fun initViewModel() {
lifecycleScope.launch {
viewModel.uiState.flowWithLifecycle(lifecycle).collectLatest { state ->
Log.d("jess", state.toString())
}
}
}
}
package com.example.mvvmcompose
// Ui State를 관리하는 data class 정의
// 게시판 UI를 가정하고 컴포넌트를 정의(제목, 내용, 사용자..)
data class MvvmUiState(
val header: String?,
val title: String?,
val content: String?,
val user: String?,
val viewCount: Int,
) {
// StateFlow 설계를 위한 초기값 설정
companion object {
fun empty(
header: String? = null,
title: String? = null,
content: String? = null,
user: String? = null,
viewCount: Int = 0,
) = MvvmUiState (
header = header,
title = title,
content = content,
user = user,
viewCount = viewCount,
)
}
}
package com.example.mvvmcompose
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
// 뷰모델 정의
class MvvmViewmodel : ViewModel() {
private val _uiState = MutableStateFlow(MvvmUiState.empty())
// uiState의 State 데이터값
val uiState: StateFlow<MvvmUiState> = _uiState.asStateFlow()
// UI Layer(Activity)에다가 게시판의 각 컴포넌트의 State 데이터를 넘겨주는 requestBoart() 함수 정의
fun requestBoard() {
// activity 시작하자마자 실행되는 함수(api 요청 or 데이터 가져오기 등)
viewModelScope.launch{
// update라는 StateFlow의 익스텐션을 활용, 게시판의 각 컴포넌트의 데이터를 update 후 저장
_uiState.update {prev ->
prev.copy(
// 데이터를 받아와서 viewModel에 데이터를 업데이트해줌
header = "내일움캠프 게시판",
title = "compose 강의",
content = "MVVM 디자인 패턴과 compose",
user = "정호정",
viewCount = 60000,
)
}
}
}
}
(참고: https://developer.android.com/topic/architecture/ui-layer?hl=ko)
'[개발] > Kotlin 활용 앱 개발' 카테고리의 다른 글
Compose - 함수 / UI 구성 (0) | 2024.07.30 |
---|---|
Compose - 함수 / 레이아웃 구성 (0) | 2024.07.30 |
Android - ViewType(뷰타입) (0) | 2024.07.18 |
Android - ViewPager2 / TabLayout (0) | 2024.07.18 |
Android - RecyclerView에서의 ListAdapter 활용 (0) | 2024.07.18 |