본문 바로가기

안드로이드

[Android] 액티비티에서 gif를 이용한 로딩 다이얼로그 띄우기

개요

Android에서 네트워크를 통해 데이터를 얻어오는 동안의 대기 시간 동안 유저로 하여금 작업이 진행 중임을 알리기 위해 로딩 다이얼로그를 띄우는 방법을 소개하는 포스팅이다.

 

절차

0. gif를 재생할 Glide 종속성 추가

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

 

1. gif 파일을 리소스 디렉토리의 raw 디렉토리에 넣기

로딩을 표시할 gif 파일을 다운로드 받거나 직접 생성하여 raw 디렉토리에 저장한다. 리소스 디렉토리에 raw가 없다면 생성한다.

 

2. 다이얼로그 xml 작성

loading_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/load_image_view"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</FrameLayout>

 

3. 코드 작성

- Application을 상속받는 BaseApplication 생성

class BaseApplication : Application(){

    override fun onCreate() {
        super.onCreate()
        instance=this
    }

    companion object {
        lateinit var instance : BaseApplication
            private set //Only BaseApplication set the instance value
    }

}

싱글톤 패턴을 활용하여 구현한다.

 

- 다이얼로그 관련 코드 작성

class BaseApplication : Application(){
    override fun onCreate() {
        super.onCreate()
        instance=this
    }


    fun progressOn(view: Activity?) {
        if (view == null || view.isFinishing)
            return

        if (dialog == null || (dialog != null && dialog!!.isShowing)) {
            dialog = AppCompatDialog(view).apply {
                setCancelable(false)
                window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
                setContentView(R.layout.loading_dialog)
                show()
            }
        }

        Glide.with(view).load(R.raw.rolling_loader)
                .apply(RequestOptions().override(50, 50))
                .into(dialog!!.findViewById<ImageView>(R.id.load_image_view) as ImageView)
    }

    fun progressOff(){
        if(dialog!=null && dialog!!.isShowing)
            dialog!!.dismiss()
    }

    companion object {
        lateinit var instance : BaseApplication
            private set //Only BaseApplication set the instance value
        var dialog: AppCompatDialog? = null
    }

}

 

- 프로젝트 어디에서든 dialog를 쉽게 띄우기 위해 Util.kt의 object에 메서드를 정의

object Util {
    fun progressOn(activity: Activity){
        BaseApplication.instance.progressOn(activity)
    }
    fun progressOff(){
        BaseApplication.instance.progressOff()
    }
}

 

- AndroidManifest.xml에서 기본 application을 BaseApplication으로 변경

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...>
    
    <application
        android:name=".application.BaseApplication"
        ...>
        ...
    </application>

</manifest>

 

4. 실제 사용

 login_btn.setOnClickListener {
            if (name_text_view.text.toString().isNotBlank())
                repository.postUser(User(name_text_view.text.toString()))
                        .doOnSubscribe { Util.progressOn(this) }
                        .doFinally { Util.progressOff() }
                        .subscribe({
                            startMainActivity(it)
                        }, {
                            Log.d(TAG, it.message)
                        })
        }

위는 RxJava+Retrofit으로 통신하는 과정에서 doOnSubscribe로 구독을 시작할 시 다이얼로그를 띄우고, 작업이 종료되었을 시 doFinally를 통해 다이얼로그를 제거하는 과정이다.

 

Reference