일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Gradle
- 코드포스
- Coroutines
- architecture
- pandas
- 쿠링
- Rxjava
- MiTweet
- Python
- Coroutine
- textfield
- boj
- 프로그래머스
- Codeforces
- TEST
- GitHub
- AWS
- 백준
- MyVoca
- 코루틴
- Compose
- androidStudio
- livedata
- 암호학
- Hilt
- ProGuard
- relay
- android
- Kotlin
- activity
- Today
- Total
이동식 저장소
Composable 매개변수 줄이기 - 오버로딩 활용 본문
Compose로 복잡한 UI를 개발하다 보면, 함수의 매개변수가 너무 많아지는 문제가 발생한다. 특히 Activity에서 호출하는 최상위 Composable은 매개변수가 많아질 수밖에 없다.
// EditSubscriptionActivity.kt
binding.composeView.setContent {
val uiState by viewModel.uiState.collectAsState()
KuringTheme {
Subscriptions(
selectedTab = uiState.selectedTab,
categories = uiState.categories,
departments = uiState.departments,
onTabClick = viewModel::onTabClick,
onCategoryClick = viewModel::onNormalSubscriptionItemClick,
onDepartmentClick = viewModel::onDepartmentSubscriptionItemClick,
onAddDepartmentButtonClick = { navigator.navigateToEditSubscribedDepartment(this) },
onSubscriptionComplete = ::onSubscriptionComplete,
modifier = Modifier.fillMaxSize(),
)
}
}
이번 글에서는 ``Subscriptions`` Composable의 매개변수를 줄여 보자.
눈속임
사실 화면에서 제공하는 기능을 줄이지 않는 이상, 콜백을 없앨 수는 없다. 따라서 이 글의 진짜 목적은 겉으로 드러나는 매개변수를 줄이는 것이다. 겉으로 드러나는 매개변수란, Compose 외부의 ``Activity``, ``Fragment``에서 제공해야 하는 매개변수를 말한다.
관찰
코드를 자세히 보면, 매개변수 9개 중 6개가 ``uiState``와 ``viewModel``로부터 제공되고 있음을 알 수 있다. 사실 ``uiState``도 ``viewModel``에서 제공되고 있으므로, ``viewModel``이 6개의 매개변수를 대체할 수 있는 것이다.
따라서 ``Subscriptions``이 실질적으로 요구하는 매개변수는 ``viewModel``, ``onAddDepartmentButtonClick``, ``onSubscriptionComplete``, ``modifier`` 총 4개이다.
새 집 다오
관찰 결과를 바탕으로 새 Composable을 작성하였다. 이 함수를 앞으로 ``간결한 Composable``이라고 부르겠다.
@Composable
fun Subscriptions(
viewModel: EditSubscriptionViewModel,
onAddDepartmentButtonClick: () -> Unit,
onSubscriptionComplete: () -> Unit,
modifier: Modifier = Modifier,
) {
val uiState by viewModel.uiState.collectAsState()
// UI
}
헌 집 줄게?
그렇다면 기존에 구현되어 있던 ``장황한 Composable``은 이제 삭제해도 되나?
@Composable
fun Subscriptions(
selectedTab: EditSubscriptionTab,
categories: List<NormalSubscriptionUiModel>,
departments: List<DepartmentSubscriptionUiModel>,
onTabClick: (EditSubscriptionTab) -> Unit,
onCategoryClick: (Int) -> Unit,
onDepartmentClick: (String) -> Unit,
onAddDepartmentButtonClick: () -> Unit,
onSubscriptionComplete: () -> Unit,
modifier: Modifier = Modifier,
) {
// 제거해야?
}
코드만 보면 그렇지만, 장황한 Composable도 나름 쓸모가 있다.
현재 Compose Preview는 ``ViewModel``을 매개변수로 받는 Composable을 지원하지 않는다. 즉 간결한 Composable을 프리뷰로 볼 수는 없으며, 프리뷰에서는 장황한 Composable만을 볼 수 있다.
따라서 Compose 외부에는 간결한 Composable을 노출하고, 장황한 Composable은 private으로 선언하여 내부 호출 및 프리뷰 용으로 사용하는 것이 제일 좋다. 코드로 정리하면 다음과 같다.
// 간결한 Composable
@Composable
fun Subscriptions(
viewModel: EditSubscriptionViewModel,
onAddDepartmentButtonClick: () -> Unit,
onSubscriptionComplete: () -> Unit,
modifier: Modifier = Modifier,
) {
val uiState by viewModel.uiState.collectAsState()
Subscriptions(
selectedTab = uiState.selectedTab,
categories = uiState.categories,
departments = uiState.departments,
onTabClick = viewModel::onTabClick,
onCategoryClick = viewModel::onNormalSubscriptionItemClick,
onDepartmentClick = viewModel::onDepartmentSubscriptionItemClick,
onAddDepartmentButtonClick = onAddDepartmentButtonClick,
onSubscriptionComplete = onSubscriptionComplete,
modifier = modifier,
)
}
// 장황한 Composable
@Composable
private fun Subscriptions(
selectedTab: EditSubscriptionTab,
categories: List<NormalSubscriptionUiModel>,
departments: List<DepartmentSubscriptionUiModel>,
onTabClick: (EditSubscriptionTab) -> Unit,
onCategoryClick: (Int) -> Unit,
onDepartmentClick: (String) -> Unit,
onAddDepartmentButtonClick: () -> Unit,
onSubscriptionComplete: () -> Unit,
modifier: Modifier = Modifier,
) {
// UI
}
// 프리뷰
@LightPreview
@Composable
private fun DepartmentPagePreview_Empty() {
KuringTheme {
Subscriptions(
selectedTab = EditSubscriptionTab.DEPARTMENT,
onTabClick = {},
categories = emptyList(),
departments = emptyList(),
onCategoryClick = {},
onDepartmentClick = {},
onAddDepartmentButtonClick = {},
onSubscriptionComplete = {},
modifier = Modifier.fillMaxSize(),
)
}
}
``Activity``에서는 간결한 Composable을 호출하면 된다.
binding.composeView.setContent {
KuringTheme {
Subscriptions(
viewModel = viewModel,
onAddDepartmentButtonClick = { navigator.navigateToEditSubscribedDepartment(this) },
onSubscriptionComplete = ::onSubscriptionComplete,
modifier = Modifier.fillMaxSize(),
)
}
}
참고 문헌
내 머릿속
'Primary > Compose' 카테고리의 다른 글
Compose에서 Icon의 크기를 IconButton만큼 키우고 싶다면? (0) | 2024.02.06 |
---|---|
ViewModel에 너무 많은 책임을 지우지 말 것 (0) | 2024.02.04 |
Accompanist Compose Navigation 라이브러리 deprecated - migration 가이드 (0) | 2024.01.01 |
TalkBack이 Compose TextField를 인식하지 못하는 문제 (1) | 2023.10.02 |
Compose에서 이미지가 흑백으로 보일 때 (0) | 2023.06.10 |