Android DialogFragment vs Dialog

244

Google merekomendasikan agar kami menggunakan DialogFragmentalih-alih sederhana Dialogdengan menggunakan Fragments API, tetapi tidak masuk akal untuk menggunakan DialogFragmentkotak pesan konfirmasi Ya-Tidak yang sederhana. Apa praktik terbaik dalam kasus ini?

tersesat
sumber
5
Singkatnya, antara lain, sederhana Dialogatau AlertDialog.Builder::create()::show()akan membuat dialog yang hilang saat Anda memutar layar.
user1032613

Jawaban:

83

Ya, gunakan DialogFragmentdan di onCreateDialogdalamnya Anda cukup menggunakan pembuat AlertDialog untuk membuat yang sederhana AlertDialogdengan tombol konfirmasi Ya / Tidak. Tidak terlalu banyak kode sama sekali.

Berkenaan dengan menangani acara di fragmen Anda akan ada berbagai cara untuk melakukannya, tetapi saya hanya mendefinisikan pesan Handlerdi saya Fragment, meneruskannya DialogFragmentmelalui konstruktornya dan kemudian mengirimkan pesan kembali ke penangan fragmen saya sebagai sesuai pada berbagai acara klik. Sekali lagi berbagai cara melakukan itu tetapi berikut ini berhasil untuk saya.

Dalam dialog, tahan pesan dan instantiate di konstruktor:

private Message okMessage;
...
okMessage = handler.obtainMessage(MY_MSG_WHAT, MY_MSG_OK);

Terapkan onClickListenerdialog Anda dan kemudian panggil handler jika sesuai:

public void onClick(.....
    if (which == DialogInterface.BUTTON_POSITIVE) {
        final Message toSend = Message.obtain(okMessage);
        toSend.sendToTarget();
    }
 }

Edit

Dan seperti Messagepaket Anda dapat menyimpannya onSaveInstanceStatedan mengembalikannya

outState.putParcelable("okMessage", okMessage);

Lalu masuk onCreate

if (savedInstanceState != null) {
    okMessage = savedInstanceState.getParcelable("okMessage");
}
PJL
sumber
4
Masalahnya bukan okMessage - masalahnya adalah okMessage targetyang akan menjadi nol jika Anda memuatnya dari sebuah Bundel. Jika target Pesan adalah nol, dan Anda gunakan sendToTarget, Anda akan mendapatkan NullPointerException - bukan karena Pesan itu nol, tetapi karena targetnya adalah.
jam
2
Apa keuntungan menggunakan DialogFragment daripada Dialog?
Raphael Petegrosso
80
Keuntungan menggunakan DialogFragment adalah bahwa semua siklus hidup dialog akan ditangani untuk Anda. Anda tidak akan pernah mendapatkan kesalahan 'dialog telah bocor ...' lagi. Pergi ke DialogFragment dan lupakan Dialog.
Snicolas
6
Saya pikir setArguments () dan getArguments () harus digunakan daripada meneruskan okMessage melalui konstruktor.
pjv
1
Yah saya pengguna Builder cukup mudah dan saya menangani manajemen aktivitas dengan android ini: configChanges = "locale | keyboardHidden | orientasi | screenSize" dan saya tidak melihat masalah dalam aplikasi ...
Renetik
67

Anda dapat membuat subkelas DialogFragment umum seperti YesNoDialog dan OkDialog, dan memasukkan judul dan pesan jika Anda sering menggunakan dialog di aplikasi Anda.

public class YesNoDialog extends DialogFragment
{
    public static final String ARG_TITLE = "YesNoDialog.Title";
    public static final String ARG_MESSAGE = "YesNoDialog.Message";

    public YesNoDialog()
    {

    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Bundle args = getArguments();
        String title = args.getString(ARG_TITLE);
        String message = args.getString(ARG_MESSAGE);

        return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, null);
                }
            })
            .create();
    }
}

Kemudian panggil menggunakan yang berikut:

    DialogFragment dialog = new YesNoDialog();
    Bundle args = new Bundle();
    args.putString(YesNoDialog.ARG_TITLE, title);
    args.putString(YesNoDialog.ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(this, YES_NO_CALL);
    dialog.show(getFragmentManager(), "tag");

Dan menangani hasilnya onActivityResult.

ashishduh
sumber
Ya, DialogFragment menangani semua acara daur hidup untuk Anda.
ashishduh
1
Saya pikir itu tidak karena setelah rotasi Dialog lama masih ada dan tetap dialihkan ke fragmen lama yang tidak ada (dialog.setTargetFragment (ini, YES_NO_CALL);) jadi setelah rotasi getTargetFragment (). OnActivityResult tidak berfungsi
Malachiasz
7
apa itu YES_NO_CALL, getFragmentManager()dan onActivityResult?
msysmilu
2
YES_NO_CALLadalah custom int yang merupakan kode permintaan. getFragmentManager()mendapatkan manajer fragmen untuk aktivitas tersebut, dan onActivityResult()merupakan metode panggilan balik siklus fragmen.
ashishduh
3
Ganti getFragmentManager () dengan getSupportFragmentManager ();
Avinash Verma
33

Gunakan DialogFragment melalui AlertDialog:


  • Sejak diperkenalkannya API level 13 :

    yang showDialog metode dari Activity yang ditinggalkan . Meminta dialog di tempat lain dalam kode tidak disarankan karena Anda harus mengelola sendiri dialognya (mis. Perubahan orientasi).

  • Perbedaan DialogFragment - AlertDialog

    Apakah mereka sangat berbeda? Dari referensi Android tentang DialogFragment :

    DialogFragment adalah fragmen yang menampilkan jendela dialog, mengambang di atas jendela aktivitasnya. Fragmen ini berisi objek Dialog, yang ditampilkan sesuai dengan keadaan fragmen. Kontrol dialog (memutuskan kapan untuk menampilkan, menyembunyikan, mengabaikannya) harus dilakukan melalui API di sini , bukan dengan panggilan langsung pada dialog.

  • Catatan lain

    • Fragmen adalah evolusi alami dalam kerangka Android karena keragaman perangkat dengan ukuran layar yang berbeda.
    • DialogFragmen dan Fragmen tersedia di perpustakaan dukungan yang membuat kelas dapat digunakan di semua versi Android yang digunakan saat ini.
Tobrun
sumber
28

Saya akan merekomendasikan menggunakan DialogFragment.

Tentu, membuat dialog "Ya / Tidak" dengannya cukup rumit mengingat bahwa itu seharusnya tugas yang agak sederhana, tetapi membuat kotak dialog serupa dengan Dialogmengejutkan juga rumit.

(Siklus hidup aktivitas membuatnya rumit - Anda harus membiarkan Activitymengelola siklus hidup kotak dialog - dan tidak ada cara untuk melewati parameter khusus misalnya pesan khusus Activity.showDialogjika menggunakan tingkat API di bawah 8)

Yang menyenangkan adalah bahwa Anda biasanya dapat membangun abstraksi sendiri DialogFragmentdengan mudah.

jam
sumber
Bagaimana Anda akan menangani panggilan balik dialog peringatan (ya, tidak)?
Alexey Zakharov
Cara termudah adalah dengan mengimplementasikan metode dalam Kegiatan hosting yang mengambil Stringparameter. Ketika pengguna mengklik "Ya", misalnya, dialog akan memanggil metode Aktivitas dengan parameter "setuju". Parameter ini ditentukan saat menampilkan dialog, misalnya AskDialog.ask ("Apakah Anda setuju dengan persyaratan ini?", "Setuju", "tidak setuju");
jam
5
Tetapi saya perlu callback di dalam fragmen, bukan aktivitas. Saya bisa menggunakan setTargetFragment dan melemparkannya ke antarmuka. Tapi itu neraka.
Alexey Zakharov
Anda juga bisa mengambil fragmen sasaran dengan menetapkan tag ke target dan menggunakan FragmentManager's findFragmentByTag. Tapi ya, itu membutuhkan sedikit kode yang adil.
jam
@AlexeyZakharov Saya tahu ini adalah sekitar 5 tahun terlambat tapi Anda bisa lulus Fragment this dan memiliki Anda Activity extendsAnda Interface. Berhati-hati dalam melakukan threading, Anda bisa menghentikan panggilan antarmuka saat Anda tidak menginginkannya jika konkurensi Anda tidak terkendali. Tidak yakin apa yang dilakukan dengan memori dan spageti dependensi melingkar, apakah ada orang lain yang suka berpadu? Opsi lainnya adalah Message/ Handlertetapi Anda mungkin masih memiliki masalah konkurensi.
tricknology
8

AlertDialogFragment Generik dengan Pola Builder

Dalam proyek saya, saya sudah digunakan AlertDialog.Buildersudah banyak sebelum saya menemukan bahwa itu bermasalah. Namun, saya tidak ingin mengubah kode sebanyak itu di mana pun di aplikasi saya. Selain itu, saya sebenarnya penggemar lewat OnClickListenerssebagai kelas anonim di mana mereka diperlukan (yaitu, ketika menggunakan setPositiveButton(), setNegativeButton()dll.) Daripada harus menerapkan ribuan metode panggilan balik untuk berkomunikasi antara fragmen dialog dan fragmen pemegang, yang dapat, dalam Pendapat saya, mengarah pada kode yang sangat membingungkan dan kompleks. Terutama, jika Anda memiliki beberapa dialog berbeda dalam satu fragmen dan kemudian perlu membedakan dalam implementasi panggilan balik antara dialog yang saat ini ditampilkan.

Oleh karena itu, saya menggabungkan berbagai pendekatan untuk membuat AlertDialogFragmentkelas pembantu umum yang dapat digunakan persis seperti AlertDialog :


LARUTAN

( PERHATIKAN bahwa saya menggunakan ekspresi Java 8 lambda dalam kode saya, jadi Anda mungkin harus mengubah bagian-bagian kode jika Anda belum menggunakan ekspresi lambda .)

/**
 * Helper class for dialog fragments to show a {@link AlertDialog}. It can be used almost exactly
 * like a {@link AlertDialog.Builder}
 * <p />
 * Creation Date: 22.03.16
 *
 * @author felix, http://flx-apps.com/
 */
public class AlertDialogFragment extends DialogFragment {
    protected FragmentActivity activity;
    protected Bundle args;
    protected String tag = AlertDialogFragment.class.getSimpleName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = getActivity();
        args = getArguments();
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = setDialogDefaults(new AlertDialog.Builder(getActivity())).create();

        if (args.containsKey("gravity")) {
            dialog.getWindow().getAttributes().gravity = args.getInt("gravity");
        }

        dialog.setOnShowListener(d -> {
            if (dialog != null && dialog.findViewById((android.R.id.message)) != null) {
                ((TextView) dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
            }
        });
        return dialog;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);

        if (args.containsKey("onDismissListener")) {
            Parcelable onDismissListener = args.getParcelable("onDismissListener");
            if (onDismissListener != null && onDismissListener instanceof ParcelableOnDismissListener) {
                ((ParcelableOnDismissListener) onDismissListener).onDismiss(this);
            }
        }
    }

    /**
     * Sets default dialog properties by arguments which were set using {@link #builder(FragmentActivity)}
     */
    protected AlertDialog.Builder setDialogDefaults(AlertDialog.Builder builder) {
        args = getArguments();
        activity = getActivity();

        if (args.containsKey("title")) {
            builder.setTitle(args.getCharSequence("title"));
        }

        if (args.containsKey("message")) {
            CharSequence message = args.getCharSequence("message");
            builder.setMessage(message);
        }

        if (args.containsKey("viewId")) {
            builder.setView(getActivity().getLayoutInflater().inflate(args.getInt("viewId"), null));
        }

        if (args.containsKey("positiveButtonText")) {
            builder.setPositiveButton(args.getCharSequence("positiveButtonText"), (dialog, which) -> {
                onButtonClicked("positiveButtonListener", which);
            });
        }

        if (args.containsKey("negativeButtonText")) {
            builder.setNegativeButton(args.getCharSequence("negativeButtonText"), (dialog, which) -> {
                onButtonClicked("negativeButtonListener", which);
            });
        }

        if (args.containsKey("neutralButtonText")) {
            builder.setNeutralButton(args.getCharSequence("neutralButtonText"), (dialog, which) -> {
                onButtonClicked("neutralButtonListener", which);
            });
        }

        if (args.containsKey("items")) {
            builder.setItems(args.getStringArray("items"), (dialog, which) -> {
                onButtonClicked("itemClickListener", which);
            });
        }

        // @formatter:off
        // FIXME this a pretty hacky workaround: we don't want to show the dialog if onClickListener of one of the dialog's button click listener were lost
        //       the problem is, that there is no (known) solution for parceling a OnClickListener in the long term (only for state changes like orientation change,
        //       but not if the Activity was completely lost)
        if (
                (args.getParcelable("positiveButtonListener") != null && !(args.getParcelable("positiveButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("negativeButtonListener") != null && !(args.getParcelable("negativeButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("neutralButtonListener") != null && !(args.getParcelable("neutralButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("itemClickListener") != null && !(args.getParcelable("itemClickListener") instanceof ParcelableOnClickListener))
        ) {
            new DebugMessage("Forgot onClickListener. Needs to be dismissed.")
                    .logLevel(DebugMessage.LogLevel.VERBOSE)
                    .show();
            try {
                dismissAllowingStateLoss();
            } catch (NullPointerException | IllegalStateException ignored) {}
        }
        // @formatter:on

        return builder;
    }

    public interface OnDismissListener {
        void onDismiss(AlertDialogFragment dialogFragment);
    }

    public interface OnClickListener {
        void onClick(AlertDialogFragment dialogFragment, int which);
    }

    protected void onButtonClicked(String buttonKey, int which) {
        ParcelableOnClickListener parcelableOnClickListener = getArguments().getParcelable(buttonKey);
        if (parcelableOnClickListener != null) {
            parcelableOnClickListener.onClick(this, which);
        }
    }

    // region Convenience Builder Pattern class almost similar to AlertDialog.Builder
    // =============================================================================================

    public AlertDialogFragment builder(FragmentActivity activity) {
        this.activity = activity;
        this.args = new Bundle();
        return this;
    }

    public AlertDialogFragment addArguments(Bundle bundle) {
        args.putAll(bundle);
        return this;
    }

    public AlertDialogFragment setTitle(int titleStringId) {
        return setTitle(activity.getString(titleStringId));
    }

    public AlertDialogFragment setTitle(CharSequence title) {
        args.putCharSequence("title", title);
        return this;
    }

    public AlertDialogFragment setMessage(int messageStringId) {
        return setMessage(activity.getString(messageStringId));
    }

    public AlertDialogFragment setMessage(CharSequence message) {
        args.putCharSequence("message", message);
        return this;
    }

    public AlertDialogFragment setPositiveButton(int textStringId, OnClickListener onClickListener) {
        return setPositiveButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setPositiveButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("positiveButtonText", text);
        args.putParcelable("positiveButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNegativeButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNegativeButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNegativeButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("negativeButtonText", text);
        args.putParcelable("negativeButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNeutralButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNeutralButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNeutralButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("neutralButtonText", text);
        args.putParcelable("neutralButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setOnDismissListener(OnDismissListener onDismissListener) {
        if (onDismissListener == null) {
            return this;
        }

        Parcelable p = new ParcelableOnDismissListener() {
            @Override
            public void onDismiss(AlertDialogFragment dialogFragment) {
                onDismissListener.onDismiss(dialogFragment);
            }
        };
        args.putParcelable("onDismissListener", p);
        return this;
    }

    public AlertDialogFragment setItems(String[] items, AlertDialogFragment.OnClickListener onClickListener) {
        args.putStringArray("items", items);
        args.putParcelable("itemClickListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setView(int viewId) {
        args.putInt("viewId", viewId);
        return this;
    }

    public AlertDialogFragment setGravity(int gravity) {
        args.putInt("gravity", gravity);
        return this;
    }

    public AlertDialogFragment setTag(String tag) {
        this.tag = tag;
        return this;
    }

    public AlertDialogFragment create() {
        setArguments(args);
        return AlertDialogFragment.this;
    }

    public AlertDialogFragment show() {
        create();
        try {
            super.show(activity.getSupportFragmentManager(), tag);
        }
        catch (IllegalStateException e1) {

            /**
             * this whole part is used in order to attempt to show the dialog if an
             * {@link IllegalStateException} was thrown (it's kinda comparable to
             * {@link FragmentTransaction#commitAllowingStateLoss()} 
             * So you can remove all those dirty hacks if you are sure that you are always
             * properly showing dialogs in the right moments
             */

            new DebugMessage("got IllegalStateException attempting to show dialog. trying to hack around.")
                    .logLevel(DebugMessage.LogLevel.WARN)
                    .exception(e1)
                    .show();

            try {
                Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
                mShownByMe.setAccessible(true);
                mShownByMe.set(this, true);
                Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
                mDismissed.setAccessible(true);
                mDismissed.set(this, false);
            }
            catch (Exception e2) {
                new DebugMessage("error while showing dialog")
                        .exception(e2)
                        .logLevel(DebugMessage.LogLevel.ERROR)
                        .show();
            }
            FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
            transaction.add(this, tag);
            transaction.commitAllowingStateLoss(); // FIXME hacky and unpredictable workaround
        }
        return AlertDialogFragment.this;
    }

    @Override
    public int show(FragmentTransaction transaction, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    @Override
    public void show(FragmentManager manager, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    protected ParcelableOnClickListener createParcelableOnClickListener(AlertDialogFragment.OnClickListener onClickListener) {
        if (onClickListener == null) {
            return null;
        }

        return new ParcelableOnClickListener() {
            @Override
            public void onClick(AlertDialogFragment dialogFragment, int which) {
                onClickListener.onClick(dialogFragment, which);
            }
        };
    }

    /**
     * Parcelable OnClickListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnClickListener extends ResultReceiver implements AlertDialogFragment.OnClickListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnClickListener() {
            super(null);
        }

        @Override
        public abstract void onClick(AlertDialogFragment dialogFragment, int which);
    }

    /**
     * Parcelable OnDismissListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnDismissListener extends ResultReceiver implements AlertDialogFragment.OnDismissListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnDismissListener() {
            super(null);
        }

        @Override
        public abstract void onDismiss(AlertDialogFragment dialogFragment);
    }


    // =============================================================================================
    // endregion
}

PEMAKAIAN

// showing a normal alert dialog with state loss on configuration changes (like device rotation)
new AlertDialog.Builder(getActivity())
        .setTitle("Are you sure? (1)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

// showing a dialog fragment using the helper class with no state loss on configuration changes
new AlertDialogFragment.builder(getActivity())
        .setTitle("Are you sure? (2)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

Saya memposting ini di sini bukan hanya untuk membagikan solusi saya, tetapi juga karena saya ingin meminta pendapat Anda kepada Anda: Apakah pendekatan ini sah atau bermasalah sampai batas tertentu?

flxapps
sumber
3
Ini adalah ide yang sangat menarik, tapi saya rasa desain API tidak berfungsi. Jika Anda meneruskan OnClickListener ke setPositiveButton (), saat perangkat diputar dan fragmen dibuat ulang dari argumen Bundle, OnClickListeners tidak akan dibuat ulang dengan benar dari Parcelable. Masalah mendasarnya adalah Anda tidak dapat membuat ulang pendengar selama rotasi, tetapi antarmuka API (yang membutuhkan antarmuka) menuntutnya. Saya berharap ini bukan masalahnya (karena saya suka ide itu).
Xargs
1
Ide bagus, tetapi seperti yang dikatakan @Xargs, itu tidak bekerja. Pendengar yang lewat tidak diciptakan kembali dengan benar pada rotasi.
Graham Borland
Hasil saya adalah bahwa itu benar-benar berfungsi pada rotasi dan melanjutkan ke aplikasi (setelah pergi ke layar awal misalnya), tetapi tidak ketika aktivitas dikembalikan setelah benar-benar hancur (maka OnClickListeners memang hilang). (Diuji pada Android 4.4.4 dan Android 5.1.1)
flxapps
Saya belum menguji implementasi yang tepat ini tetapi dari apa yang telah saya uji, pendengar parcelable yang diteruskan ke bundel fragmen dipanggil dengan benar di buat ulang. Saya tidak tahu mengapa tetapi tampaknya berhasil.
Saad Farooq
@ flxapps, dalam hal tampilan khusus, bagaimana Anda bisa mendapatkan tampilan anak dan mengubah sifat mereka atau menerapkan pendengar? Di kelas Anda, Anda tidak mengembalikan instance dialog apa pun dan itu dapat menyebabkan pengecualian jika seseorang akan mencoba untuk mendapatkan tampilan anak
Zubair Rehman
5

Bolehkah saya menyarankan sedikit penyederhanaan jawaban @ ashishduh:

public class AlertDialogFragment extends DialogFragment {
public static final String ARG_TITLE = "AlertDialog.Title";
public static final String ARG_MESSAGE = "AlertDialog.Message";

public static void showAlert(String title, String message, Fragment targetFragment) {
    DialogFragment dialog = new AlertDialogFragment();
    Bundle args = new Bundle();
    args.putString(ARG_TITLE, title);
    args.putString(ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(targetFragment, 0);
    dialog.show(targetFragment.getFragmentManager(), "tag");
}

public AlertDialogFragment() {}

@NonNull
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState)
{
    Bundle args = getArguments();
    String title = args.getString(ARG_TITLE, "");
    String message = args.getString(ARG_MESSAGE, "");

    return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .create();
}

Ini menghilangkan kebutuhan pengguna (kelas) untuk terbiasa dengan internal komponen dan membuat penggunaannya sangat sederhana:

AlertDialogFragment.showAlert(title, message, this);

PS Dalam kasus saya, saya membutuhkan dialog peringatan sederhana sehingga itulah yang saya buat. Anda dapat menerapkan pendekatan ke Ya / Tidak atau jenis lain yang Anda butuhkan.

KAPAK
sumber
1

Gunakan Dialog untuk dialog ya atau tidak yang sederhana.

Ketika Anda membutuhkan tampilan yang lebih kompleks di mana Anda perlu mendapatkan siklus hidup seperti oncreate, meminta izin, setiap siklus hidup menimpa saya akan menggunakan fragmen dialog. Dengan demikian Anda memisahkan izin dan kode lain yang diperlukan dialog untuk beroperasi tanpa harus berkomunikasi dengan aktivitas panggilan.

Gustavo Baiocchi Costa
sumber