일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- androidStudio
- textfield
- boj
- Compose
- 암호학
- Codeforces
- android
- 프로그래머스
- activity
- Kotlin
- Coroutine
- MyVoca
- relay
- 백준
- TEST
- livedata
- Gradle
- Hilt
- MiTweet
- GitHub
- Coroutines
- 코드포스
- architecture
- Python
- 코루틴
- AWS
- 쿠링
- Rxjava
- pandas
- ProGuard
- Today
- Total
이동식 저장소
Compose Example - sunflower 본문
Google의 샘플 앱 중 하나인 sunflower를 간단히 리뷰한다. ``compose`` 브랜치 기준으로 작성하였다.
이미지 로딩
비동기적으로 이미지를 가져오려면 Glide나 Coil 등의 외부 라이브러리를 사용해야 한다. Sunflower에서는 Compose를 지원하는 Coil을 이용하여 이미지를 로딩하였다.
@Composable
private fun PlantImage(
imageUrl: String,
imageHeight: Dp,
modifier: Modifier = Modifier,
placeholderColor: Color = MaterialTheme.colors.onSurface.copy(0.2f)
) {
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data(data = imageUrl)
.crossfade(true)
.build()
)
Image(
painter = painter,
contentScale = ContentScale.Crop,
contentDescription = null,
modifier = modifier
.fillMaxWidth()
.height(imageHeight)
)
if (painter.state is AsyncImagePainter.State.Loading) {
Box(
modifier = Modifier
.fillMaxSize()
.background(placeholderColor)
)
}
}
전형적인 이미지 로딩 코드이다. 아래 부분의 ``if``문은 이미지가 로딩 중일 때 보여줄 placeholder를 구현한 것이다. Placeholder도 여러 방법으로 구현할 수 있는데, Accompanist의 ``Modifier.placeholder`` 함수를 사용할 수도 있고, ``ImageBuilde.placeholder(drawableId)`` 함수를 사용해도 된다.
난 Accompanist를 애용하는 편이다.
애니메이션
@Composable
fun PlantDetails(
plant: Plant,
isPlanted: Boolean,
callbacks: PlantDetailsCallbacks,
modifier: Modifier = Modifier
) {
// animated float value
val toolbarAlpha = transition.animateFloat(
transitionSpec = { spring(stiffness = Spring.StiffnessLow) }, label = ""
) { toolbarTransitionState ->
if (toolbarTransitionState == ToolbarState.HIDDEN) 0f else 1f
}
Box(
Modifier
.fillMaxSize()
.systemBarsPadding()
// attach as a parent to the nested scroll system
.nestedScroll(nestedScrollConnection)
) {
// toolbar alpha is animated
PlantToolbar(
toolbarState, plant.name, callbacks,
toolbarAlpha = { toolbarAlpha.value },
contentAlpha = { contentAlpha.value }
)
}
}
``toolbarAlpha``는 ``transition``의 값에 따라 animate되는 Float 값이다. 값이 animate되므로 툴바의 투명도가 부드럽게 전환된다.
Dimension 처리
Sunflower는 View System와 Compose를 함께 사용하고 있다. 따라서 string이나 dimension value 등의 리소스를 두 시스템 모두에서 사용할 수 있게 해야 한다.
View System에서는 xml에 값을 바로 사용하면 되고, Compose에서는 ``dimensionResource(id)`` 함수를 이용하면 값을 불러올 수 있다. 자주 사용하는 값이라면 다음 코드처럼 별도의 상수로 선언해도 된다.
object Dimens {
val PaddingSmall: Dp
@Composable get() = dimensionResource(R.dimen.margin_small)
val PaddingNormal: Dp
@Composable get() = dimensionResource(R.dimen.margin_normal)
val PaddingLarge: Dp = 24.dp
val PlantDetailAppBarHeight: Dp
@Composable get() = dimensionResource(R.dimen.plant_detail_app_bar_height)
val ToolbarIconPadding = 12.dp
val ToolbarIconSize = 32.dp
}
``get()``에 ``@Composable``이 붙은 이유는 ``dimensionResource`` 함수가 ``@Composable``이기 때문이다.
순수 Compose 앱에서도 리소스 xml 파일을 유용하게 사용할 수 있다. 화면 크기 또는 locale에 따라 다른 값을 적용해야 하는 경우에도 쉽게 대응할 수 있기 때문이다.
레이아웃은 몰라도 리소스 정도는 xml로 작성해줄 수 있지 ㅎㅎ
'Primary > Compose' 카테고리의 다른 글
[Compose] 반응형 앱 구현 실전 (4) | 2022.10.20 |
---|---|
[Compose] Movable Content (0) | 2022.08.13 |
Compose가 UI를 그리는 과정 (0) | 2022.08.13 |
Compose의 Stability에 관하여 (0) | 2022.07.05 |
[Compose] 커스텀 뷰 - 세로 방향 불규칙 그리드 만들기 (0) | 2022.02.09 |