본문 바로가기

Android + Kotlin

[Android + Kotlin] Shimmer 라이브러리를 이용하여 로딩 화면 만들기

반응형

오늘은 페이스북의 Shimmer 라이브러리를 이용하여 리스트 로딩 화면을 만들어 보겠습니다.

 

 

Shimmer 라이브러리는 위의 이미지와 같이 오른쪽에서 왼쪽으로 뭔가 흐르는 듯한 애니메이션을 쉽게 구현할 수 있도록 도와줍니다.

 

 

Shimmer for Android

About Shimmer is an Android library that provides an easy way to add a shimmer effect to any view in your Android app. It is useful as an unobtrusive loading indicator that was originally developed for Facebook Home. Watch Introductory Video Shimmer for An

facebook.github.io

 

위의 사이트에 가시면 Shimmer 라이브러리의 설명과 사용 방법에 대해 상세히 소개되어있습니다.

참고 하시면 좋을 것 같습니다.

 

 

아래 코드는 기존에 구현했던 리스트 소스에 추가 구현하도록 하겠습니다.

전체 소스가 궁금하신 분은 맨 하단의 Github 링크를 확인해주세요.

 


 

첫번째로 Shimmer 라이브러리를 프로젝트의 build.gradle(module 수준)에 implementation을 합니다.

 

implementation 'com.facebook.shimmer:shimmer:0.5.0'

 

 


 

다음으로 로딩 아이템 뷰를 구현을 할 차례입니다.

목록 아이템과 상이하지 않도록 비슷한 아이템 layout으로 구현 합니다. (list_item_image_loading.xml)

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/iv_loading"
        android:layout_width="160dp"
        android:layout_height="120dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:background="#ffaaaaaa"/>

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="180dp"
        android:layout_height="24dp"
        app:layout_constraintTop_toTopOf="@id/iv_loading"
        app:layout_constraintStart_toEndOf="@id/iv_loading"
        android:layout_marginStart="8dp"
        android:background="#ffaaaaaa"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 


 

이제 activity layout xml 파일에 목록(RecyclerView) 위에 로딩 화면을 구현합니다.

아래 코드에서 ShimmerFrameLayout 부분을 보시면 되는데, 로딩 화면인 layout 맨 위로 올라오도록 위치시켰습니다.

그리고, 앞서 구현했던 list_item_image_loading.xml 아이템 레이아웃을 5개정도 include 해줌으로써 화면에 가득 보이도록 추가해 주었습니다.

(화면의 height가 긴 경우엔 추가로 include를 해주시면 됩니다.)

 

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_list"
        ... />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/empty_view"
        ... />

    <com.facebook.shimmer.ShimmerFrameLayout
        android:id="@+id/sf_loading"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:shimmer_auto_start="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <include layout="@layout/list_item_image_loading"/>
            <include layout="@layout/list_item_image_loading"/>
            <include layout="@layout/list_item_image_loading"/>
            <include layout="@layout/list_item_image_loading"/>
            <include layout="@layout/list_item_image_loading"/>

        </LinearLayout>

    </com.facebook.shimmer.ShimmerFrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 


 

이제 화면(LoremPicsumListActivity.kt)에 리스트 데이터를 가져오는 부분과 연동하여 로딩화면이 표시되도록 구현합니다.

위의 layout에서 app:shimmer_auto_start="true" 속성을 통해서, 화면 진입시 자동으로 로딩 애니메이션이 시작하도록 설정하였기 때문에, 코드에서는 로딩 종료에 대한 구현만 하면 됩니다.

 

imageListAdapter.loadStateFlow.distinctUntilChangedBy { it.refresh }
    .filter { it.refresh is LoadState.NotLoading }
    .collect {
        // hide loading
        ...
        // hide shimmer loading
        with(binding.sfLoading) {
            if(isShimmerStarted) {
                stopShimmer()
                isVisible = false
            }
        }
        // empty view
		...
    }

 

위의 코드와 같이, 데이터 로딩이 완료된 시점에서 isShimmerStarted 값을 확인하여 로딩이 표시중인지 여부를 확인합니다.

로딩이 표시중이라면 stopShimmer() 함수를 호출하여 로딩 애니메이션을 멈춰주고, 로딩 뷰를 숨겨주면 끝! 입니다.

 


 

이제 구현된 코드를 실행시키면 아래 이미지와 같이 동작합니다.

 

 

 

전체 프로젝트 코드는 아래 Github 링크를 확인해주세요.

 

 

GitHub - rcbuilders/RemindSampleApp: https://heeeju4lov.tistory.com/ 블로그에서 Android + Kotlin 강좌에서 사용함.

https://heeeju4lov.tistory.com/ 블로그에서 Android + Kotlin 강좌에서 사용함. - GitHub - rcbuilders/RemindSampleApp: https://heeeju4lov.tistory.com/ 블로그에서 Android + Kotlin 강좌에서 사용함.

github.com

 

반응형