Compose랑 친해지기 feat. 토이 프로젝트

햄햄·2022년 7월 8일
0

Compose

목록 보기
6/7

최근 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)
)

터치가 발생할 때 마다 offsetYsnapTo를 통해 값을 설정하고, 터치가 끝나면 0f로 animateTo하면서 받아오는 연속적인 값을 통해 애니메이션을 구현할 수 있었습니다.
위 경우 tween 애니메이션을 사용하였고, 다른 AnimationSpec을 지정할 수도 있습니다.

느낀점

더 공부하고 익숙해져야겠다고 생각했습니다.

소스 코드는 아래에서 확인할 수 있습니다.
https://github.com/Haemin-Park/ComposeMovie

0개의 댓글