0

既存のプロジェクトのコードをクリーンアップし、Activity の呼び出しに関する警告を削除しようとしてshowDialog()、一連の関連ダイアログを新しいDialogFragmentクラスに移動しました。正常に動作していますが、特定のダイアログでキャンセル ボタンを押すと、常に前のダイアログ (バック スタックに保存されたもの) に戻りますが、キャンセル ボタンですべてのダイアログを閉じて戻る必要があります。メイン アクティビティのビューに。

戻るボタンを押すと、引き続きバック スタックの前のダイアログに戻る必要があります。

これが私の現在のコードです。2 つのダイアログのみを含めるように単純化しましたが、これら 2 つの間のチェーンにはさらにいくつかのダイアログがあり、実際のアプリケーションでimport()は が呼び出される前に表示されます。

public class ImportDialog extends DialogFragment {
    private int mType = 0;

    public static final int DIALOG_IMPORT_HINT = 0;
    // ... several more
    public static final int DIALOG_IMPORT = 8;



    public interface ImportDialogListener {
        public void import();
        public void showImportDialog(int type);
        public void dismissAllDialogFragments();
    }


    /**
     * A set of dialogs which deal with importing a file
     * 
     * @param dialogType An integer which specifies which of the sub-dialogs to show
     */
    public static ImportDialog newInstance(int dialogType) {
        ImportDialog f = new ImportDialog();
        Bundle args = new Bundle();
        args.putInt("dialogType", dialogType);
        f.setArguments(args);
        return f;
    }


    @Override
    public AlertDialog onCreateDialog(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mType = getArguments().getInt("dialogType");
        Resources res = getResources();
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        setCancelable(true);

        switch (mType) {
            case DIALOG_IMPORT_HINT:
                // First dialog
                builder.setTitle("Title");
                builder.setMessage("Message");
                builder.setPositiveButton(res.getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((ImportDialogListener) getActivity()).showImportDialog(DIALOG_IMPORT_SELECT);
                    }
                });
                builder.setNegativeButton(res.getString(R.string.dialog_cancel), mNegativeClickListener);
                return builder.create();

            // ... several more

            case DIALOG_IMPORT:
                // Second dialog
                builder.setTitle("Different title");
                builder.setMessage("Different message");
                builder.setPositiveButton(res.getString(R.string.import_message_add),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                ((ImportDialogListener) getActivity()).import();
                            }
                        });

                builder.setNegativeButton(res.getString(R.string.dialog_cancel), mNegativeClickListener);
                builder.setCancelable(true);
                return builder.create();

            default:
                return null;
        }
    }

    private DialogInterface.OnClickListener mNegativeClickListener = new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            ((ImportDialogListener) getActivity()).dismissAllDialogFragments(); 
        }
    };
}

次に、メインのアクティビティで、ImportDialogListener次のようにインターフェイスを実装します。

public void showImportDialog(int type) {
    // 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 = getSupportFragmentManager().beginTransaction();
    Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    // save transaction to the back stack (input argument is optional name) so it can be reversed
    ft.addToBackStack(null);
    DialogFragment newFragment = ImportDialog.newInstance(type);
    newFragment.show(ft, "dialog");
}

public void import() {
    // Do stuff
}

// Dismiss whatever dialog is showing... THIS IS THE PART THAT DOESN'T WORK
public void dismissAllDialogFragments() {
    getSupportFragmentManager().popBackStack("dialog", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        DialogFragment df = (DialogFragment) prev;
        df.dismiss();
    }
}

どうすればそれを機能させることができますか?ここで根本的に間違ったことをしていますか?

4

1 に答える 1

4

トランザクションをバック スタックに追加するときに、バック スタック状態の名前を指定します。例:ダイアログ

変化する

ft.addToBackStack(null);

ft.addToBackStack("dialog");

バック スタックの状態名に一致するエントリをバック スタックから削除するには、FragmentManager.popBackStackを使用します。これにより、スタックの下部に到達するか、別の名前のバック スタック状態エントリに到達するまで、名前がダイアログのすべてのバック スタック状態が上部から削除されます。ダイアログで明示的に却下を呼び出す必要はありません。

public void dismissAllDialogFragments() {
    getSupportFragmentManager().popBackStack("dialog", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
于 2014-09-01T05:15:58.280 に答える