[Android / Compose] Skeleton Shimmer Effect 처리

2024. 7. 9. 16:20· Development/Android
반응형

리스트나 화면을 구성하는 동안의 Loading 상태에서 자주 사용되는 Shimmer View. 기존 XML 방식에서는 각종 라이브러리를 활용하여 많이 구현되었습니다.
하지만 Compose에서는 아직 직접 구현이 필요한 듯하여 다른 분들의 코드를 참고하여 구현을 진행했습니다.

먼저 위 이미지와 동일한 형태의 컴포저블을 구현해야합니다.
스켈레톤 효과를 입혀줄 틀을 만들어주는 것입니다.

    @Composable
    fun PlaceholderItem() {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
                .height(72.dp)
        ) {
            Box(
                modifier = Modifier
                    .size(60.dp)
                    .shimmerEffect(8.dp)
            )
            Spacer(modifier = Modifier.width(16.dp))
            Column(
                modifier = Modifier
                    .weight(1f)
                    .padding(top = (2.5).dp)
                    .height(60.dp)
            ) {
                Box(
                    modifier = Modifier
                        .height(16.dp)
                        .fillMaxWidth(0.7f)
                        .shimmerEffect(4.dp)
                )
                Spacer(modifier = Modifier.height(2.dp))
                Box(
                    modifier = Modifier
                        .height(16.dp)
                        .fillMaxWidth(0.5f)
                        .shimmerEffect(4.dp)
                )
                Spacer(modifier = Modifier.height(2.dp))
                Box(
                    modifier = Modifier
                        .height(16.dp)
                        .fillMaxWidth(0.3f)
                        .shimmerEffect(4.dp)
                )
            }
        }
    }

 

이제 컴포저블의 속성을 변경해 줄 Modifier를 기준으로 Shimmer Effect 확장 함수를 만들어줍니다.
composed {}는 Modifier 확장 함수를 구성 가능한 함수로 만들어 줍니다. 이는 상태를 기억하고 재구성할 수 있게 해줍니다.

fun Modifier.shimmerEffect(radius: Dp): Modifier = composed {
    var size by remember { mutableStateOf(IntSize.Zero) }
    val transition = rememberInfiniteTransition(label = "")
    val startOffsetX by transition.animateFloat(
        initialValue = -2 * size.width.toFloat(),
        targetValue = 2 * size.width.toFloat(),
        animationSpec = infiniteRepeatable(
            animation = tween(1000)
        ),
        label = ""
    )
    ...

initialValue와 targetValue로 애니메이션 시작 종료 지점을 지정해 주고, 1초 간격으로 무한 반복 동작하도록 구성합니다.

size는 변화하는 컴포저블의 크기를 저장하기 위함입니다.

 

...
	background(
        brush = Brush.linearGradient(
            colors = listOf(
                Color(0xFFEFF0F1),
                Color(0xFFE0E0E0),
                Color(0xFFEFF0F1)
            ),
            start = Offset(startOffsetX, 0f),
            end = Offset(startOffsetX + size.width.toFloat(), size.height.toFloat())
        ),
        shape = RoundedCornerShape(radius)
    ).onGloballyPositioned { size = it.size }
}

background는 컴포저블의 배경을 설정합니다. 여기서 애니메이션을 적용하고, 스켈레톤 그러데이션 처리 색상을 지정해 줍니다.

Brush.linearGradient로 선형 그러데이션을 지정합니다. 그리고 start end 값을 지정해 줌으로써 대각선 방향으로 애니메이션 처리가 되도록 설정해 줄 수 있습니다.
shape는 필요한 스켈레톤 뷰의 모양에 따라 다르게 구현이 가능합니다. 저 같은 경우에는 모서리가 둥글어야 해서 RoundedCornerShape 활용했습니다.

마지막으로 onGloballyPositioned를 통해 변화하는 컴포저블의 크기를 변수에 저장하여 애니메이션 처리를 진행할 수 있습니다.

활용 시에는 아래처럼 선언하면 되겠습니다.

Spacer(modifier = Modifier.height(2.dp))
Box(
    modifier = Modifier
        .height(16.dp)
        .fillMaxWidth(0.5f)
        .shimmerEffect(4.dp)
)

 

반응형
저작자표시 (새창열림)
'Development/Android' 카테고리의 다른 글
  • [Kotlin] HashMap을 특정 데이터 클래스로 변환
  • [Android / Kotlin] Compose Custom Tab Row 사용하기
  • [Android / Compose] java.lang.illegalstateexception: viewtreelifecycleowner not found from android.widget.framelayout in ~ 대응
  • [Android] Kotlin Compose 활용해서 Tooltip 직접 구현하기
SeungYong.Lee
SeungYong.Lee
반응형
SeungYong.Lee
Win-Dev
SeungYong.Lee
전체
오늘
어제
  • All (236) N
    • Development (136) N
      • Android (132) N
      • iOS (0)
      • Flutter (4)
      • Backend (0)
    • Algorithm (5)
    • Knowledge (5)
      • IT (2)
      • Science (0)
      • ETC & Tip (3)
    • Today I Learn (28)
    • Coding Test (62)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 안녕하세요. 반갑습니다 :)

인기 글

태그

  • dfs
  • hilt
  • glance
  • Android
  • 프로그래머스
  • Collection
  • Imageview
  • Retrofit
  • Animation
  • exception
  • Flutter
  • Java
  • Kotlin
  • Widget
  • 코틀린
  • 비동기처리
  • 코딩테스트
  • coroutine
  • compose
  • HTTP

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
SeungYong.Lee
[Android / Compose] Skeleton Shimmer Effect 처리
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.