DialogFragmentを正しく閉じる方法は?


121

ドキュメントdismiss()Dialogクラスのメソッドに対してこれを言っています:

このダイアログを閉じて、画面から削除します。このメソッドは、任意のスレッドから安全に呼び出すことができます。ダイアログが閉じられたときにクリーンアップを行うためにこのメソッドをオーバーライドしないでくださいonStop()。代わりにそれをに実装してください。

私のコードでは、私がgetDialog().dismiss()することはそれを却下するための呼び出しです。しかし、私は他に何もしていませんonStop()。したがってDialogFragment、メモリリークなどを回避するために、を正しく閉じる方法を正確に尋ねています。

回答:


197

tl; dr: aを閉じる正しい方法DialogFragmentdismiss() 、DialogFragmentで直接使用することです


詳細DialogFragment状態のドキュメント

ダイアログの制御(表示、非表示、閉じるタイミングの決定)は、ダイアログを直接呼び出すのではなく、ここでAPIを介して行う必要があります。

したがって、ダイアログgetDialog().dismiss()を呼び出すため、を使用しないでください。代わりに、DialogFragment自体のメソッドを使用する必要があります。dismiss() dismiss()

public void dismiss()

フラグメントとそのダイアログを閉じます。フラグメントがバックスタックに追加された場合、このエントリまでのすべてのバックスタック状態がポップされます。それ以外の場合、フラグメントを削除するために新しいトランザクションがコミットされます。

ご覧のように、これはダイアログを閉じるだけでなく、プロセスに関連するフラグメントトランザクションの処理も処理します。

onStop手動でのクリーンアップが必要なリソース(ファイルのクローズ、カーソルのクローズなど)を明示的に作成した場合にのみ使用する必要があります。それでも、基礎となるDialog onStopではなくDialogFragment をオーバーライドしますonStop


1
@ScootrNova:すべきではありません。おそらく他の場所にバグがあります。どのようにしてフラグメントを作成していますか?
ハインツィ

protected void showDialogFragment(final DialogFragment fragment) {final FragmentTransaction fTransaction = getSupportFragmentManager().beginTransaction(); fTransaction.addToBackStack(null); fragment.show(fTransaction, "dialog");} 厄介なワンライナーでごめんなさい!しかし、そうかもしれませんが、当面は、当面はDialogFragmentsを閉じる別の方法を記述しました。dismiss()メソッドを使用してそれらを却下する方法は、タグでフラグメントを検索し、それがnullでない場合はそれに対してdismiss()を実行することでした。ああ、そうですnew。そのメソッドに渡す直前にフラグメントを処理しています。
Charles Madere 14年

2
@ScootrNova:うーん、何も問題はありません-一方、互換性ライブラリを使用したことがないので、確信が持てません。たぶん、最小限の自己完結型の例を作成し、それについて新しい質問を始めることが理にかなっているかもしれません。
ハインツィ14年

@CharlesMadere当時、あなたは解決策を見つけましたか?
JCarlosR 2016年

申し訳ありません、@ JCarlos、これは何年も前のことでした、私にはわかりません。
Charles Madere

76

DialogFragmentはこれを閉じるためのより良い方法はこれだと思います:

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

これにより、への参照を保持する必要がなくなりDialogFragment、どこからでもそれを閉じることができます。


7

このコードだけを使用してみませんか?

dismiss();

独自にDialog Fragmentを却下したい場合。このコードは、ダイアログを閉じるダイアログフラグメント内に配置するだけです。

例えば:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

これにより、画面に表示されている最近のダイアログフラグメントが閉じます。

お役に立てば幸いです。


いつも働いていない
Mahmoud Heretani

5

私はテレルの答えに賛成票を投じました。これをKotlinユーザーに投稿したかっただけです。

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}

簡単なコードはうまくいきます、更新バディをありがとう!!
Ayush Katuwal

4

Terel回答のKotlinバージョン

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()

1

あなたはあなたを解雇するべきですのでDialogonPause()それを上書きしてください。

また、閉じる前にnull、以下のスニペットを確認して表示することができます。

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

彼はすでにdismiss()とそのDialogFragmentについてやっていると書いています。
パレシュマヤニ

私はこれがDialogとDialogFragmentsの両方で機能すると思います@PareshMayani
Venky

2
@PareshMayaniは正しいVenkyだと思います。DialogFragmentGoogle のチュートリアルでは、onPause()使用されているメソッドはまったく示されていません。しかし、私はあなたがしていることを理解していると思います。ただし、ユーザーがを呼び出さない場合のポイントは何ですかonPause()。これは、フラグメントが呼び出されていることをシステムが認識している場合です。いつ、ユーザーがキャンセルしたとしましょう。その場合、それを閉じるためのより良い方法は何ですか?
アンディ

1

他の回答には公式ドキュメントへの参照(DialogFragment Reference)がありますが、そこに示されている例についての言及はありません。

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

これにより、現在表示されているダイアログがすべて削除され、引数を使用して新しいDialogFragmentが作成され、バックスタックに新しい状態として表示されます。トランザクションがポップされると、現在のDialogFragmentとそのDialogが破棄され、前のDialogFragment(存在する場合)が再表示されます。この場合、DialogFragmentがポップを処理することに注意してください。Dialogのトランザクションは、それとは別に破棄されます。

私のニーズのために私はそれを次のように変更しました:

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);

1

他の回答に追加すると、DialogFragmentフルスクリーンの呼び出しdismiss()がある場合、フラグメントバックスタックからDialogFragmentがポップされません。回避策はonBackPressed()、親アクティビティを呼び出すことです。

このようなもの:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}

今日は
救ってください

0

破棄するフラグメントからdismiss()を呼び出すだけです。

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });

0

ナビゲーショングラフで<fragment>タグを使用してフラグメントを定義すると(全画面のdialogfragmentの場合)、dialogfragmentがdismiss()コマンドで閉じないことがわかりました。代わりに、バックスタックをポップする必要がありました。

findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();

ただし、同じdialogfragmentが<dialog>タグ付きのナビゲーショングラフで定義されている場合、正常にdismiss()機能します。


0
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.