본문 바로가기

Dailycoding/Android

shimmer library를 사용해서 스켈레톤 로딩 화면

 

결과 화면

 

 

1️⃣  dependencies 라이브러리 추가

// shimmer
implementation("com.facebook.shimmer:shimmer:0.5.0")

 

  • shimmer github 

 

 

GitHub - facebookarchive/shimmer-android: An easy, flexible way to add a shimmering effect to any view in an Android app.

An easy, flexible way to add a shimmering effect to any view in an Android app. - facebookarchive/shimmer-android

github.com

 

 

2️⃣  ReclerView 에 들어가는 item 

 

item_rv.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="12dp">

    <ImageView
        android:id="@+id/imageView_item_rv"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="fitCenter"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView_item_rv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView_item_rv"
        tools:text="textArea" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

3️⃣  스켈레톤 로딩화면에 들어갈 item 

 

item_shimmer.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:orientation="vertical"
    android:padding="12dp">

    <ImageView
        android:id="@+id/imageView_item_shimmer"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:background="@color/cardview_shadow_start_color"
        android:scaleType="fitCenter"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView_item_shimmer"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:background="@color/cardview_shadow_start_color"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView_item_shimmer" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

  • 위에서 만든 ReclerView 에 들어가는 item 과 유사하게 구현해야 스켈레톤 로딩 이후 화면이 자연스럽다

 

4️⃣  activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item_rv" />

    <com.facebook.shimmer.ShimmerFrameLayout
        android:id="@+id/shimmerFrameLayout_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

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

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

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

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

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

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

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

        </androidx.appcompat.widget.LinearLayoutCompat>

    </com.facebook.shimmer.ShimmerFrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

  • ShimmerFrameLayout 안에 3️⃣ 에서 만든 화면을 include 해서 여러개 넣어주면 된다

 

 

5️⃣  MainActivity

 

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        binding = ActivityMainBinding.inflate(layoutInflater)

        viewModel = ViewModelProvider(this)[MainViewModel::class.java]
        viewModel.getAllData()

        observeData()

        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }

    private fun observeData() {
        viewModel.result.observe(this) { dataList ->

            // 데이터 로딩이 너무 빨리 일어나서 코루틴으로 딜레이를 줌
            GlobalScope.launch(Dispatchers.Main) {
                delay(1500)

                // 데이터 로딩 완료 시 Shimmer 애니메이션 중지
                binding.shimmerFrameLayoutMain.stopShimmer()
                binding.shimmerFrameLayoutMain.visibility = View.GONE

                binding.recyclerViewMain.run {
                    adapter = MainAdapter(dataList)
                    layoutManager = LinearLayoutManager(context)
                }
            }
        }
    }
}

 

 


전체 코드

 

 

Blog/Project/skeletonUi at develop · wjdwntjd55/Blog

Contribute to wjdwntjd55/Blog development by creating an account on GitHub.

github.com

 

 


참고한 자료

 

 

[Android] 스켈레톤 로딩 화면 구현하기 - Facebook shimmer library

사용자가 어떠한 요청을 했는데 화면에 아무런 변화가 없다면 어떤 느낌을 받을까요? 요청이 제대로 들어갔는지, 앱이 고장 난 건지 사용자는 알 수가 없습니다. 따라서 데이터를 로딩 중에는

leveloper.tistory.com

 

 

 

 

[Android / Kotlin] shimmer library를 사용하여 스켈레톤 로딩 화면 만들기

Youtube Data Api를 사용하여 미디어 앱을 만드는 중 Api를 호출하고 데이터를 수신 하여 RecyclerView에 보여주기까지 몇 초의 시간이 걸렸다. 사용자의 입장에서 생각했을 때 아무런 반응이 없고 빈 화

velog.io

 

'Dailycoding > Android' 카테고리의 다른 글

Data Binding  (0) 2024.08.27
CoordinatorLayout  (0) 2024.08.21
wifi 없을 때 Room 사용해서 화면에 표현  (0) 2024.08.19
Viewpager2 활용해서 banner 구현  (0) 2024.06.01
Fragment 화면 전환 시 상태 유지하기  (0) 2024.05.29