최근 Compose를 공부하고 있습니다. Compose를 좀 더 잘 알고 싶기 때문에 간단한 프로젝트를 구현하고 있습니다.
지브리 영화 api(https://ghibliapi.herokuapp.com)와 색상 이름을 코드로 바꿔주는 Color api(https://api.color.pizza)를 사용해 간단한 프로젝트를 구현했습니다.
1. 영화 목록 페이지
영화 목록 페이지에서는 받아온 데이터를 노출합니다.
2. 영화 상세 페이지
목록의 아이템을 클릭하면 상세 페이지로 이동하게 됩니다.
3. 등장인물 목록 페이지
[
{
"id": "ba924631-068e-4436-b6de-f3283fa848f0",
"name": "Ashitaka",
"gender": "male",
"age": "late teens",
"eye_color": "brown",
"hair_color": "brown",
"films": [],
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
"url": "https://ghibliapi.herokuapp.com/people/ba924631-068e-4436-b6de-f3283fa848f0"
},
지브리 영화 등장인물 데이터의 경우 색상 이름이 주어지기 때문에 색상 이름을 색상 코드로 변환하는 Color api를 사용한 후, 해당 색상을 백그라운드 컬러로한 등장인물 목록을 노출합니다.
등장인물 아이템을 클릭하면 얼굴 모양 UI가 생성되고, 이를 터치하면 scale이 달라지고 터치가 끝나면 위에 달라붙도록 구현을 했습니다.
간단한 토이 프로젝트를 구현하면서 새롭게 배운점이 있었습니다.
위 화면에서 영화에 관한 출시일, 러닝타임, 별점을 확인할 수 있습니다. 이 때, 텍스트 사이에 아이콘을 넣고 싶었습니다.
이를 InlineTextContent
를 통해 구현할 수 있습니다.
InlineTextContent
란 text layout에 삽입하고 싶은 composable을 저장하는 class입니다. InlineTextContent
에서 placeholder
라는 필드를 확인할 수 있는데,
이는 text layout에 삽입하기 위한 공간을 예약하기 위해 필요한 것 입니다. placeholder
에서 width와 height 그리고 align 방식을 정의할 수 있습니다.
따라서
val inlineContent = mapOf(
Pair(
starId,
InlineTextContent(
Placeholder(
width = 1.em,
height = 1.em,
placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter
)
) {
Image(
imageVector = Icons.Rounded.Star,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colors.onBackground),
alignment = Alignment.Center
)
}),
...
삽입하고 싶은 inline content 목록을 만들어 둔 뒤,
Text(
text = buildAnnotatedString {
appendInlineContent(dateId, dateId)
append(releaseDate)
...
appendInlineContent
하는 방식으로 구현할 수 있습니다.
Compose는 여러 애니메이션을 쉽게 구현할 수 있습니다.
위 예제는 터치중에는 scale이 달라지고 터치가 끝나면 위에 달라붙습니다.
이 때 위로 달라붙는 애니메이션을 위해 Animatable
를 사용했습니다.
Animatable
은 값이 animateTo
를 통해 변경될 때 값을 애니메이션으로 표시할 수 있는 value holder입니다.
animateTo
를 사용하면 연속적으로 값이 변경됩니다.
또한, AnimationSpec
을 사용해 애니메이션 사양을 지정할 수 있습니다.
offsetY.snapTo(it.y - pxFaceSize / 2)
...
offsetY.animateTo(
targetValue = 0f,
animationSpec = tween(durationMillis = 1000)
)
터치가 발생할 때 마다 offsetY
에 snapTo
를 통해 값을 설정하고, 터치가 끝나면 0f로 animateTo
하면서 받아오는 연속적인 값을 통해 애니메이션을 구현할 수 있었습니다.
위 경우 tween 애니메이션을 사용하였고, 다른 AnimationSpec
을 지정할 수도 있습니다.
더 공부하고 익숙해져야겠다고 생각했습니다.
소스 코드는 아래에서 확인할 수 있습니다.
https://github.com/Haemin-Park/ComposeMovie