汎用的なIndicatorDialog
Androidには、ProgressBar
という標準で備わっているIndicatorのコンポーネントが存在します。
ですが、今回は、カスタム化されたIndicatorを表示したいという人のための記事になります。
[参考] ProgressBarについて
目次
- 素材を用意
- レイアウト作成
- themes.xmlの修正
- ImageUtilクラス作成
- カスタムDialogFragmentの作成
- 使い方(呼び出し方)
- 補足
1. 素材を用意
まず、表示させるためのIndicatorを用意します。
以下のIndicatorを作成するサイトがあるので、GIFなどで用意します。
https://loading.io/
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)
また、通信終了時に解除したい場合などは、リスナーなどから上記をセットしてください。