Edited at

DialogFragmentをちゃんと1度だけ表示するようにする

More than 1 year has passed since last update.

DialogFragmentを表示する場合は以下のように tag を渡して show を呼びます。

dialog.show(supportFragmentManager, tag)

なので以下のように supportFragmentManager に同じ tag を持った DialogFragment があるかどうか確認してから show してあげれば1度だけの表示は実装できそうな気がします。

if ((supportFragmentManager.findFragmentByTag(tag) as? DialogFragment)?.dialog == null) {

dialog.show(supportFragmentManager, tag)
}

ただし show の場合は処理が Handler に渡されるため、即座に次の show が呼ばれば場合に supportFragmentManagertag があることが保証されません。つまり、同時タップや高速タップにより DialogFragment が複数表示される可能性があります。

そこで、以下のように show から showNow を使うようにしてあげます。

if ((supportFragmentManager.findFragmentByTag(tag) as? DialogFragment)?.dialog == null) {

dialog.showNow(supportFragmentManager, tag)
}

これで1度だけの表示ができそうです。

最初のうちは DialogFragment の表示方法について調べても show を使っているものばかりなので showNow があることに気づかないことも多いので覚えておくと良さそうです。

ちなみにですが showNow では Fragment のトランザクションで commitNow がつかわれ、 show では commit が使われてします。

public void show(FragmentManager manager, String tag) {

mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}

public void showNow(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commitNow();
}

これらの違いについては他の記事を参照すると良いでしょう。