こんにちは、新米Androidエンジニアの鶴田です。今回はAndroidで同じダイアログを二重で表示させない方法を紹介します。ダイアログ表示のトリガーとなるボタンなどを素早くタップしたときによく起こる現象です。他サイトでも同じテーマの記事がいくつかありますが、比較的シンプルに実装できたので記事にしました。
※開発言語はKotlinです

アプローチ

今回は以下のコードのようにボタンを押すたびにDialogFragmentのインスタンスの作成し、表示するようなケースを想定しています。

button.setOnClickListener { 
  val dialogFragment = CustomDialogFragment()
  dialogFragment.show(this.fragmentManager, "tag1")
}

実装手順としては、
DialogFragment#show()をオーバーライド
→FragmentManager#findFragmentByTag()でDialogFragmentが既に生成済みかをチェック
→生成されてなければ新規でダイアログを表示し、生成済みなら新たにダイアログを表示しない(super.show()を呼ばない)

というような流れです。

実装コード

class CustomDialogFragment : DialogFragment() {
  ...
  
  override fun show(manager: FragmentManager, tag: String?) {
  	if (!checkShowingDialog(manager, tag)) {
  	  super.show(manager, tag)
  	}
  }
  
  ...
}

if (!checkShowingDialog(manager, tag))←ここで同じダイアログが既に表示されているか判定しています。

private fun checkShowingDialog(manager: FragmentManager, tag: String?): Boolean {
  val dialogFragment = manager.findFragmentByTag(tag ?: "")
  dialogFragment?.let {
    if (it is DialogFragment) {
      it.dialog?.let {
        return true
      }
    }
  }
  return false
}

FragmentManagerが同じタグのDaiglogFragmentが見つければtrueを返しています。

注意点

dialogFragment.show(fragmentmanager, null)のようにタグがnullになってしまうとFragmentMangerがDialogFragmentを識別できなくなってしまうので注意が必要です。必ず、タグには任意のString型のデータを入れてください。

おわりに

どうでしたか?追加するコードも少なくシンプルな構造になっていると思います。ダイアログを実装する際は是非参考にしてください。

© 2018. SuperSoftware Co., Ltd. All Rights Reserved.