مربّعات حوار

تجربة طريقة ComposeAllowed
Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي ننصح بها لنظام التشغيل Android. تعرَّف على كيفية إضافة مكونات في Compose.

مربع الحوار هو نافذة صغيرة تطلب من المستخدم إجراء القرار أو إدخال معلومات إضافية. لا يملأ مربع الحوار الشاشة تُستخدم عادةً للأحداث المشروطة التي تتطلب من المستخدمين اتخاذ إجراء قبل يمكنه المتابعة.

صورة تعرض مربّع حوار أساسيًا
الشكل 1. مربّع حوار أساسي

Dialog الفئة هي الفئة الأساسية لمربعات الحوار، ولكن لا تنشئ مثيلاً لـ Dialog مباشرةً. بدلاً من ذلك، يمكنك استخدام إحدى الفئات الفرعية التالية:

AlertDialog
مربع حوار يمكن أن يعرض عنوانًا، ويمكن اختيار ثلاثة أزرار كحد أقصى، وقائمة قابلة للاختيار العناصر أو تخطيط مخصص.
DatePickerDialog أو TimePickerDialog
مربّع حوار يتضمّن واجهة مستخدم محدّدة مسبقًا تتيح للمستخدم اختيار تاريخ الوقت.

تحدد هذه الفئات نمط وهيكل مربع الحوار الخاص بك. تحتاج أيضًا إلى CANNOT TRANSLATE DialogFragment كحاوية لمربع الحوار. توفّر الفئة DialogFragment كل عناصر التحكم اللازمة لإنشاء مربع الحوار وإدارة مظهره، بدلاً من استدعاء الطرق في الكائن Dialog.

إنّ استخدام DialogFragment لإدارة مربّع الحوار يجعلها صحيحة. التعامل مع أحداث مراحل النشاط، مثل النقر على زر الرجوع أو التدوير الشاشة. وتتيح لك الفئة DialogFragment أيضًا إعادة استخدام واجهة المستخدم الخاصة بمربع الحوار كمكون قابل للتضمين في واجهة مستخدم أكبر، تمامًا مثل تقليدي Fragment — مثل مثلاً، عندما تريد أن تظهر واجهة مستخدم مربّع الحوار بشكل مختلف على الأجهزة الكبيرة والصغيرة الشاشات.

توضح الأقسام التالية في هذا المستند كيفية استخدام DialogFragment مع AlertDialog الخاص بك. إذا أردت إنشاء منتقي التاريخ أو الوقت، فاقرأ إضافة أدوات اختيار إلى التطبيق.

إنشاء جزء من مربّع الحوار

يمكنك إنجاز مجموعة متنوعة من تصميمات مربّعات الحوار، بما في ذلك والتخطيطات وتلك الموضحة في التصميم المتعدد الأبعاد مربّعات الحوار: من خلال تمديد DialogFragment وإنشاء AlertDialog في onCreateDialog() .

على سبيل المثال، إليك AlertDialog أساسي تتم إدارته من خلال DialogFragment:

Kotlin

class StartGameDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            // Use the Builder class for convenient dialog construction.
            val builder = AlertDialog.Builder(it)
            builder.setMessage("Start game")
                .setPositiveButton("Start") { dialog, id ->
                    // START THE GAME!
                }
                .setNegativeButton("Cancel") { dialog, id ->
                    // User cancelled the dialog.
                }
            // Create the AlertDialog object and return it.
            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}

class OldXmlActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_old_xml)

        StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG")
    }
}

Java

public class StartGameDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction.
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_start_game)
               .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // START THE GAME!
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancels the dialog.
                   }
               });
        // Create the AlertDialog object and return it.
        return builder.create();
    }
}
// ...

StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG");

عند إنشاء مثيل لهذه الفئة واستدعاء show() الموجودة على هذا الكائن، سيظهر مربع الحوار كما هو موضح في الشكل التالي.

صورة تعرض مربّع حوار أساسيًا مع زرَّي إجراءات
الشكل 2. مربّع حوار يتضمن رسالة ومربّعَين وأزرار الإجراءات.

يقدم القسم التالي مزيدًا من التفاصيل حول استخدام AlertDialog.Builder واجهات برمجة التطبيقات لإنشاء مربع الحوار.

وبناءً على مدى تعقيد مربّع الحوار، يمكنك تنفيذ مجموعة متنوعة من طُرق معاودة الاتصال الأخرى في DialogFragment، بما في ذلك جميع طرق دورة حياة الأجزاء الأساسية.

إنشاء مربّع حوار للتنبيه

تتيح لك الفئة AlertDialog إنشاء مجموعة متنوّعة من مربّعات الحوار. التصميمات وغالبًا ما تكون فئة الحوار الوحيدة التي تحتاجها. كما هو موضح في ما يلي هناك ثلاث مناطق لمربع حوار التنبيه:

  • العنوان: وهو اختياري ولا يُستخدم إلا عندما تكون منطقة المحتوى تشغلها رسالة أو قائمة أو تنسيق مخصص تفصيلي. إذا كنت بحاجة إلى اذكر رسالة أو سؤالاً بسيطًا، فأنت لست بحاجة إلى عنوان.
  • منطقة المحتوى: يمكن أن تعرض رسالة أو قائمة أو محتوى مخصّصًا آخر التصميم.
  • أزرار الإجراءات: يمكن أن يكون هناك ما يصل إلى ثلاثة أزرار إجراءات في .

توفّر الفئة AlertDialog.Builder واجهات برمجة تطبيقات تتيح لك إنشاء. AlertDialog مع هذه الأنواع من المحتوى، بما في ذلك التصميم.

لإنشاء AlertDialog، عليك اتّباع الخطوات التالية:

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setMessage("I am the message")
    .setTitle("I am the title")

val dialog: AlertDialog = builder.create()
dialog.show()

Java

// 1. Instantiate an AlertDialog.Builder with its constructor.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

// 2. Chain together various setter methods to set the dialog characteristics.
builder.setMessage(R.string.dialog_message)
       .setTitle(R.string.dialog_title);

// 3. Get the AlertDialog.
AlertDialog dialog = builder.create();

ينشئ مقتطف الرمز السابق مربّع الحوار هذا:

صورة تعرض مربّع حوار يحتوي على عنوان ومنطقة محتوى وزرَّي إجراءات.
الشكل 3. تخطيط التنبيه الأساسي .

إضافة أزرار

لإضافة أزرار إجراءات مثل تلك الموجودة في الشكل 2، استدعِ setPositiveButton() أو setNegativeButton() الطرق:

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setMessage("I am the message")
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons.
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User taps OK button.
           }
       });
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User cancels the dialog.
           }
       });
// Set other dialog properties.
...

// Create the AlertDialog.
AlertDialog dialog = builder.create();

تتطلّب طُرق set...Button() عنوانًا زر - يوفره مورد السلسلة—و CANNOT TRANSLATE DialogInterface.OnClickListener يحدد الإجراء الذي يجب اتخاذه عندما ينقر المستخدم على الزر.

هناك ثلاثة أزرار إجراءات يمكنك إضافتها:

  • إيجابي: استخدِم هذا الخيار لقبول الإجراء ومتابعته ( "حسنًا" إجراء).
  • سلبي: استخدِم هذا الخيار لإلغاء الإجراء.
  • محايد: استخدِم هذا الخيار عندما لا يرغب المستخدم في المتابعة إجراء ما ولكن لا يريد بالضرورة الإلغاء. تظهر بين الأزرار الإيجابية والسلبية. على سبيل المثال، قد يكون الإجراء "تذكيري لاحقًا".

يمكنك إضافة نوع واحد فقط من كل نوع زر إلى AlertDialog. بالنسبة مثال، لا يمكن أن يكون لديك أكثر من عبارة "إيجابي" .

يمنحك مقتطف الرمز السابق مربّع حوار للتنبيه كما يلي:

صورة تعرض مربّع حوار للتنبيه يحتوي على عنوان ورسالة وزرَّي إجراء.
الشكل 4. سيظهر مربّع حوار للتنبيه مع عنوان ورسالة وزرَي إجراءات.

إضافة قائمة

هناك ثلاثة أنواع من القوائم المتاحة مع AlertDialog. واجهات برمجة التطبيقات:

  • تمثّل هذه السمة قائمة تقليدية ذات اختيار واحد.
  • قائمة اختيار واحد دائمة (أزرار اختيار).
  • قائمة خيارات متعدّدة ثابتة (مربّعات اختيار)

لإنشاء قائمة اختيار واحد مثل القائمة في الشكل 5، استخدم setItems() :


Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setItems(arrayOf("Item One", "Item Two", "Item Three")) { dialog, which ->
        // Do something on item tapped.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.pick_color)
           .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int which) {
               // The 'which' argument contains the index position of the selected item.
           }
    });
    return builder.create();
}

يُنشئ مقتطف الرمز هذا مربّع حوار كما يلي:

صورة تعرض مربّع حوار مع عنوان وقائمة
الشكل 5. مربّع حوار يحتوي على عنوان وقائمة

لا يمكن عرض القائمة لأن القائمة تظهر في منطقة محتوى مربع الحوار لكل من رسالة وقائمة. عيِّن عنوانًا لمربع الحوار باستخدام setTitle() لتحديد عناصر القائمة، اتصل بـ setItems()، ثم أدخِل صفيفة. وبدلاً من ذلك، يمكنك تحديد قائمة باستخدام setAdapter() يتيح لك ذلك الرجوع إلى القائمة باستخدام بيانات ديناميكية - مثل من قاعدة بيانات - باستخدام ListAdapter

في حال الاحتفاظ بنسخة احتياطية من قائمتك باستخدام ListAdapter، استخدِم دائمًا Loader لكي يتم تحميل المحتوى بشكل غير متزامن. يتم توضيح ذلك بشكل أكبر في إنشاء التنسيقات مع محوّل الحمّلات:

إضافة قائمة ذات خيارات متعدّدة ثابتة أو فردية

لإضافة قائمة بعناصر متعددة الخيارات (مربعات اختيار) أو عناصر أحادية الاختيار (أزرار الاختيار)، فاستخدم setMultiChoiceItems() أو setSingleChoiceItems() على التوالي.

على سبيل المثال، إليك كيفية إنشاء قائمة خيارات متعدّدة مثل كما هو موضح في الشكل 6 الذي يحفظ العناصر المحددة في ArrayList:

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setMultiChoiceItems(
        arrayOf("Item One", "Item Two", "Item Three"), null) { dialog, which, isChecked ->
        // Do something.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    selectedItems = new ArrayList();  // Where we track the selected items
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Set the dialog title.
    builder.setTitle(R.string.pick_toppings)
    // Specify the list array, the items to be selected by default (null for
    // none), and the listener through which to receive callbacks when items
    // are selected.
           .setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checks the item, add it to the selected
                       // items.
                       selectedItems.add(which);
                   } else if (selectedItems.contains(which)) {
                       // If the item is already in the array, remove it.
                       selectedItems.remove(which);
                   }
               }
           })
    // Set the action buttons
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // User taps OK, so save the selectedItems results
                   // somewhere or return them to the component that opens the
                   // dialog.
                   ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   ...
               }
           });

    return builder.create();
}
صورة تعرض مربّع حوار يحتوي على قائمة بالعناصر المتعدّدة الخيارات.
الشكل 6. تمثّل هذه السمة قائمة تتضمّن عناصر متعددة الخيارات.

يمكن الحصول على مربع حوار للتنبيه ذو اختيار واحد على النحو التالي:

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setSingleChoiceItems(
        arrayOf("Item One", "Item Two", "Item Three"), 0
    ) { dialog, which ->
        // Do something.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

        String[] choices = {"Item One", "Item Two", "Item Three"};
        
        AlertDialog.Builder builder = AlertDialog.Builder(context);
        builder
                .setTitle("I am the title")
                .setPositiveButton("Positive", (dialog, which) -> {

                })
                .setNegativeButton("Negative", (dialog, which) -> {

                })
                .setSingleChoiceItems(choices, 0, (dialog, which) -> {

                });

        AlertDialog dialog = builder.create();
        dialog.show();

ينتج عن ذلك المثال التالي:

صورة تعرض مربّع حوار يحتوي على قائمة بالعناصر المستندة إلى خيار واحد.
الشكل 7. تمثّل هذه السمة قائمة بعناصر ذات اختيار واحد.

إنشاء تنسيق مخصص

إذا كنت تريد تنسيقًا مخصصًا في مربع حوار، فأنشئ تنسيقًا وأضفه إلى AlertDialog عن طريق الاتصال setView() في الكائن AlertDialog.Builder.

صورة تعرض تنسيق مربّع حوار مخصّص
الشكل 8. تنسيق مخصّص لمربّعات الحوار

يملأ التنسيق المخصّص نافذة مربّع الحوار تلقائيًا، ولكن لا يزال بإمكانك استخدام AlertDialog.Builder طريقة لإضافة أزرار وعنوان

على سبيل المثال، في ما يلي ملف التنسيق لمربّع الحوار المخصّص السابق التخطيط:

res/layout/dialog_signin.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:src="@drawable/header_logo"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:scaleType="center"
        android:background="#FFFFBB33"
        android:contentDescription="@string/app_name" />
    <EditText
        android:id="@+id/username"
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="4dp"
        android:hint="@string/username" />
    <EditText
        android:id="@+id/password"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:fontFamily="sans-serif"
        android:hint="@string/password"/>
</LinearLayout>

لتكبير التنسيق في DialogFragment، يمكنك الحصول على LayoutInflater مع getLayoutInflater() والاتصال inflate() المعلمة الأولى هي معرّف مورد التنسيق، والمعلمة الثانية هي العرض الأصلي للتخطيط. يمكنك بعد ذلك الاتصال setView() لوضع التخطيط في مربع الحوار. يظهر ذلك في المثال التالي.

Kotlin

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return activity?.let {
        val builder = AlertDialog.Builder(it)
        // Get the layout inflater.
        val inflater = requireActivity().layoutInflater;

        // Inflate and set the layout for the dialog.
        // Pass null as the parent view because it's going in the dialog
        // layout.
        builder.setView(inflater.inflate(R.layout.dialog_signin, null))
                // Add action buttons.
                .setPositiveButton(R.string.signin,
                        DialogInterface.OnClickListener { dialog, id ->
                            // Sign in the user.
                        })
                .setNegativeButton(R.string.cancel,
                        DialogInterface.OnClickListener { dialog, id ->
                            getDialog().cancel()
                        })
        builder.create()
    } ?: throw IllegalStateException("Activity cannot be null")
}

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Get the layout inflater.
    LayoutInflater inflater = requireActivity().getLayoutInflater();

    // Inflate and set the layout for the dialog.
    // Pass null as the parent view because it's going in the dialog layout.
    builder.setView(inflater.inflate(R.layout.dialog_signin, null))
    // Add action buttons
           .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // Sign in the user.
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   LoginDialogFragment.this.getDialog().cancel();
               }
           });
    return builder.create();
}

إذا كنت تريد مربع حوار مخصصًا، فيمكنك عرض Activity كـ بدلاً من استخدام واجهات برمجة تطبيقات Dialog. أنشئ نشاطًا اضبط مظهره على Theme.Holo.Dialog في <activity> عنصر البيان:

<activity android:theme="@android:style/Theme.Holo.Dialog" >

يظهر النشاط الآن في نافذة مربّع حوار بدلاً من وضع ملء الشاشة.

تمرير الأحداث مرة أخرى إلى مضيف مربّع الحوار

عندما ينقر المستخدم على أحد أزرار الإجراءات في مربع الحوار أو يحدد عنصرًا من القائمة، قد يُجري DialogFragment الإجراء نفسه، ولكنك غالبًا ما تريد تسليم الحدث إلى النشاط أو مقطع يفتح مربع الحوار. للقيام بذلك، حدد واجهة باستخدام طريقة لكل نوع من أحداث النقر. ثم تنفيذ هذه الواجهة في المضيف المكون الذي يتلقى أحداث الإجراءات من مربع الحوار.

على سبيل المثال، إليك DialogFragment الذي يحدّد واجهة. والذي من خلاله يُسلم الأحداث إلى النشاط المضيف:

Kotlin

class NoticeDialogFragment : DialogFragment() {
    // Use this instance of the interface to deliver action events.
    internal lateinit var listener: NoticeDialogListener

    // The activity that creates an instance of this dialog fragment must
    // implement this interface to receive event callbacks. Each method passes
    // the DialogFragment in case the host needs to query it.
    interface NoticeDialogListener {
        fun onDialogPositiveClick(dialog: DialogFragment)
        fun onDialogNegativeClick(dialog: DialogFragment)
    }

    // Override the Fragment.onAttach() method to instantiate the
    // NoticeDialogListener.
    override fun onAttach(context: Context) {
        super.onAttach(context)
        // Verify that the host activity implements the callback interface.
        try {
            // Instantiate the NoticeDialogListener so you can send events to
            // the host.
            listener = context as NoticeDialogListener
        } catch (e: ClassCastException) {
            // The activity doesn't implement the interface. Throw exception.
            throw ClassCastException((context.toString() +
                    " must implement NoticeDialogListener"))
        }
    }
}

Java

public class NoticeDialogFragment extends DialogFragment {

    // The activity that creates an instance of this dialog fragment must
    // implement this interface to receive event callbacks. Each method passes
    // the DialogFragment in case the host needs to query it.
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    // Use this instance of the interface to deliver action events.
    NoticeDialogListener listener;

    // Override the Fragment.onAttach() method to instantiate the
    // NoticeDialogListener.
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // Verify that the host activity implements the callback interface.
        try {
            // Instantiate the NoticeDialogListener so you can send events to
            // the host.
            listener = (NoticeDialogListener) context;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface. Throw exception.
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

ينشئ النشاط الذي يستضيف مربع الحوار مثيلاً لمربع الحوار مع الدالة الإنشائية لجزء مربع الحوار وتتلقى أحداث مربع الحوار من خلال تنفيذ واجهة NoticeDialogListener:

Kotlin

class MainActivity : FragmentActivity(),
        NoticeDialogFragment.NoticeDialogListener {

    fun showNoticeDialog() {
        // Create an instance of the dialog fragment and show it.
        val dialog = NoticeDialogFragment()
        dialog.show(supportFragmentManager, "NoticeDialogFragment")
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following
    // methods defined by the NoticeDialogFragment.NoticeDialogListener
    // interface.
    override fun onDialogPositiveClick(dialog: DialogFragment) {
        // User taps the dialog's positive button.
    }

    override fun onDialogNegativeClick(dialog: DialogFragment) {
        // User taps the dialog's negative button.
    }
}

Java

public class MainActivity extends FragmentActivity
                          implements NoticeDialogFragment.NoticeDialogListener{
    ...
    public void showNoticeDialog() {
        // Create an instance of the dialog fragment and show it.
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following
    // methods defined by the NoticeDialogFragment.NoticeDialogListener
    // interface.
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // User taps the dialog's positive button.
        ...
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // User taps the dialog's negative button.
        ...
    }
}

نظرًا لأن النشاط المضيف ينفذ NoticeDialogListener—التي يتم فرضها من قِبل onAttach() الموضحة في المثال السابق - يمكن لجزء مربع الحوار استخدِم طرق معاودة الاتصال بالواجهة لعرض أحداث النقر إلى النشاط:

Kotlin

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        return activity?.let {
            // Build the dialog and set up the button click handlers.
            val builder = AlertDialog.Builder(it)

            builder.setMessage(R.string.dialog_start_game)
                    .setPositiveButton(R.string.start,
                            DialogInterface.OnClickListener { dialog, id ->
                                // Send the positive button event back to the
                                // host activity.
                                listener.onDialogPositiveClick(this)
                            })
                    .setNegativeButton(R.string.cancel,
                            DialogInterface.OnClickListener { dialog, id ->
                                // Send the negative button event back to the
                                // host activity.
                                listener.onDialogNegativeClick(this)
                            })

            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }

Java

public class NoticeDialogFragment extends DialogFragment {
    ...
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Build the dialog and set up the button click handlers.
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_start_game)
               .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the positive button event back to the host activity.
                       listener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the negative button event back to the host activity.
                       listener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
}

إظهار مربع حوار

عندما تريد إظهار مربع الحوار، أنشئ مثيلاً DialogFragment والاتصال show(), واجتياز FragmentManager واسم علامة لجزء مربّع الحوار.

يمكنك الحصول على FragmentManager من خلال الاتصال getSupportFragmentManager() من صفحة FragmentActivity أو من خلال إجراء getParentFragmentManager() من Fragment. راجِع ما يلي للاطّلاع على مثال:

Kotlin

fun confirmStartGame() {
    val newFragment = StartGameDialogFragment()
    newFragment.show(supportFragmentManager, "game")
}

Java

public void confirmStartGame() {
    DialogFragment newFragment = new StartGameDialogFragment();
    newFragment.show(getSupportFragmentManager(), "game");
}

أما الوسيطة الثانية، "game"، فهي اسم علامة فريد المستخدم لحفظ حالة الجزء واستعادتها عند الضرورة. تشير العلامة أيضًا تتيح لك التحكم في الجزء من خلال استدعاء findFragmentByTag()

إظهار مربّع حوار بملء الشاشة أو كجزء مضمّن

قد ترغب في ظهور جزء من تصميم واجهة المستخدم كمربع حوار في بعض وكجزء بملء الشاشة أو جزء مضمّن في مواضع أخرى. يمكنك أيضًا وتريد أن تظهر بشكل مختلف حسب حجم شاشة الجهاز. تشير رسالة الأشكال البيانية توفّر صف واحد (DialogFragment) المرونة لإنجاز هذا الإجراء، لأنّه يمكن أن يعمل كعنصر Fragment قابل للتضمين.

ومع ذلك، لا يمكنك استخدام AlertDialog.Builder أو ملف آخر Dialog من الكائنات لإنشاء مربع الحوار في هذه الحالة. إذا كنت ترغب في DialogFragment ليكون قابلاً للتضمين، حدّد واجهة المستخدم لمربع الحوار في التخطيط، ثم تحميل التخطيط في onCreateView() معاودة الاتصال.

في ما يلي مثال على DialogFragment يمكن أن يظهر كمربّع حوار أو جزء قابل للتضمين، باستخدام تخطيط يسمى purchase_items.xml:

Kotlin

class CustomDialogFragment : DialogFragment() {

    // The system calls this to get the DialogFragment's layout, regardless of
    // whether it's being displayed as a dialog or an embedded fragment.
    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        // Inflate the layout to use as a dialog or embedded fragment.
        return inflater.inflate(R.layout.purchase_items, container, false)
    }

    // The system calls this only when creating the layout in a dialog.
    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // The only reason you might override this method when using
        // onCreateView() is to modify the dialog characteristics. For example,
        // the dialog includes a title by default, but your custom layout might
        // not need it. Here, you can remove the dialog title, but you must
        // call the superclass to get the Dialog.
        val dialog = super.onCreateDialog(savedInstanceState)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        return dialog
    }
}

Java

public class CustomDialogFragment extends DialogFragment {
    // The system calls this to get the DialogFragment's layout, regardless of
    // whether it's being displayed as a dialog or an embedded fragment.
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout to use as a dialog or embedded fragment.
        return inflater.inflate(R.layout.purchase_items, container, false);
    }

    // The system calls this only when creating the layout in a dialog.
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using
        // onCreateView() is to modify the dialog characteristics. For example,
        // the dialog includes a title by default, but your custom layout might
        // not need it. Here, you can remove the dialog title, but you must
        // call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

يحدد المثال التالي ما إذا كان سيتم عرض الجزء كمربع حوار أو واجهة مستخدم بملء الشاشة، بناءً على حجم الشاشة:

Kotlin

fun showDialog() {
    val fragmentManager = supportFragmentManager
    val newFragment = CustomDialogFragment()
    if (isLargeLayout) {
        // The device is using a large layout, so show the fragment as a
        // dialog.
        newFragment.show(fragmentManager, "dialog")
    } else {
        // The device is smaller, so show the fragment fullscreen.
        val transaction = fragmentManager.beginTransaction()
        // For a polished look, specify a transition animation.
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity.
        transaction
                .add(android.R.id.content, newFragment)
                .addToBackStack(null)
                .commit()
    }
}

Java

public void showDialog() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    CustomDialogFragment newFragment = new CustomDialogFragment();

    if (isLargeLayout) {
        // The device is using a large layout, so show the fragment as a
        // dialog.
        newFragment.show(fragmentManager, "dialog");
    } else {
        // The device is smaller, so show the fragment fullscreen.
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // For a polished look, specify a transition animation.
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity.
        transaction.add(android.R.id.content, newFragment)
                   .addToBackStack(null).commit();
    }
}

لمزيد من المعلومات حول إجراء معاملات التجزئة، راجع الأقسام:

في هذا المثال، تحدّد القيمة المنطقية mIsLargeLayout ما إذا يجب أن يستخدم الجهاز الحالي تصميم التنسيق الكبير للتطبيق وبالتالي ستظهر كمربع حوار بدلاً من ملء الشاشة. إن أفضل طريقة لضبط هذا النوع من منطقية هي الإعلان عن مصدر منطقية قيمة مع طريقة بديلة المورد لأحجام الشاشات المختلفة. على سبيل المثال، إليك اثنان إصدارات من مورد القيم المنطقية لأحجام الشاشات المختلفة:

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

ويمكنك بعد ذلك إعداد قيمة mIsLargeLayout أثناء النَّشَاطْ onCreate() كما هو موضح في المثال التالي:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    isLargeLayout = resources.getBoolean(R.bool.large_layout)
}

Java

boolean isLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    isLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

عرض نشاط في شكل مربّع حوار على الشاشات الكبيرة

بدلاً من عرض مربع حوار كواجهة مستخدم بملء الشاشة على الشاشات الصغيرة، يمكنك الحصول على إلى النتيجة نفسها من خلال عرض Activity كمربع حوار بحجم كبير الشاشات. يعتمد النهج الذي تختاره على تصميم تطبيقك، ولكن إظهار وغالبًا ما يكون النشاط كمربع حوار مفيدًا عندما يكون التطبيق مصمَّمًا لمؤسسات صغيرة الشاشات وترغب في تحسين التجربة على الأجهزة اللوحية من خلال عرض نشاط قصير الأجل كمربع حوار.

لعرض نشاط كمربّع حوار على الشاشات الكبيرة فقط، يمكنك تطبيق Theme.Holo.DialogWhenLarge مظهر لعنصر البيان <activity>:

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >

لمزيد من المعلومات حول تصميم أنشطتك باستخدام المظاهر، يمكنك الاطّلاع على الأنماط والمظاهر:

إغلاق مربع حوار

عندما ينقر المستخدم على زر إجراء تم إنشاؤه باستخدام AlertDialog.Builder، يغلق النظام مربّع الحوار نيابةً عنك.

ويغلق النظام أيضًا مربّع الحوار عندما ينقر المستخدم على عنصر في مربّع حوار. إلا عندما تستخدم القائمة أزرار الاختيار أو مربعات الاختيار. بخلاف ذلك، يمكنك إغلاق مربع الحوار يدويًا من خلال استدعاء dismiss() على DialogFragment.

إذا كنت بحاجة إلى تنفيذ إجراءات معيّنة عند إزالة مربّع الحوار، يمكنك تنفيذ onDismiss() في DialogFragment.

ويمكنك أيضًا إلغاء مربّع حوار. هذا حدث خاص إلى أن المستخدم يغادر مربع الحوار دون إكمال المهمة. هذا النمط تحدث إذا نقر المستخدم على الزر "رجوع" أو نقر على الشاشة خارج مربع الحوار المنطقة أو إذا كنت تطلب cancel() في Dialog، مثلاً ردًا على طلب "إلغاء" الزر في .

كما هو موضّح في المثال السابق، يمكنك الرد على حدث الإلغاء من خلال جارٍ التنفيذ onCancel() في صف DialogFragment.