1
1

More than 1 year has passed since last update.

汎用的なIndicatorDialog

Last updated at Posted at 2021-12-08

汎用的なIndicatorDialog

Androidには、ProgressBarという標準で備わっているIndicatorのコンポーネントが存在します。
ですが、今回は、カスタム化されたIndicatorを表示したいという人のための記事になります。

[参考] ProgressBarについて
image.png

目次

  1. 素材を用意
  2. レイアウト作成
  3. themes.xmlの修正
  4. ImageUtilクラス作成
  5. カスタムDialogFragmentの作成
  6. 使い方(呼び出し方)
  7. 補足

1. 素材を用意

まず、表示させるためのIndicatorを用意します。
以下のIndicatorを作成するサイトがあるので、GIFなどで用意します。
https://loading.io/

progress_indicator.gif

progress_indicator.gifというファイルを作成

2. レイアウト作成

layout/indicator_layout.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="match_parent"
    android:background="@android:color/transparent">

    <ImageView
        android:id="@+id/progressImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:tag="progress_image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3. themes.xmlの修正

values/themes.xmlを修正

    <style name="Theme.IndicatorDialog" parent="Theme.MaterialComponents.Light.Dialog">
        <!-- タイトル非表示 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 透過させる -->
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

4. ImageUtilクラス作成

ImageUtil.kt

object ImageUtil {
    @RequiresApi(Build.VERSION_CODES.P)
    @JvmStatic
    fun getGifAnimationDrawable(context: Context, fileName: String): AnimatedImageDrawable {
        val source = ImageDecoder.createSource(context.assets, fileName)
        return ImageDecoder.decodeDrawable(source) as? AnimatedImageDrawable
            ?: throw ClassCastException()
    }
}

5. カスタムDialogFragmentの作成

IndicatorDialog.ktを作成

class IndicatorDialog : DialogFragment() {
    @RequiresApi(Build.VERSION_CODES.P)
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        val view = inflater.inflate(R.layout.indicator_dialog, container, false)
        val imageView = view.findViewWithTag<ImageView>("progress_image")
        setImage(imageView)
        return view
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = Dialog(requireActivity(), R.style.Theme_IndicatorDialog)
        dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.window!!.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
        return dialog
    }

    @RequiresApi(Build.VERSION_CODES.P)
    fun setImage(imageView: ImageView) {
        val drawable = ImageUtil.getGifAnimationDrawable(requireContext(), "progress_indicator.gif")
        imageView.setImageDrawable(drawable)
        drawable?.start()
    }
}

6. 使い方(呼び出し方)

activityで呼ぶ場合

IndicatorDialog().show(supportFragmentManager, "indicator")

fragmentで呼ぶ場合

IndicatorDialog().show(parentFragmentManager, "indicator")

7. 補足

画面のタッチの有効/無効をしたい場合は、以下をセットしてください。

// 無効化
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)

// 無効化解除
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)

また、通信終了時に解除したい場合などは、リスナーなどから上記をセットしてください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1