القوائم هي مكوّن شائع لواجهة المستخدم في العديد من أنواع التطبيقات. لتوفير تجربة مستخدم مألوفة ومتسقة، استخدِم واجهات برمجة تطبيقات
Menu
لعرض إجراءات المستخدم وخيارات أخرى في أنشطتك.
يوضّح هذا المستند كيفية إنشاء الأنواع الأساسية الثلاثة من القوائم أو عروض الإجراءات على جميع إصدارات Android:
- قائمة الخيارات وشريط التطبيقات
- قائمة الخيارات هي المجموعة الأساسية لعناصر القائمة الخاصة
بالنشاط. وهو المكان الذي تضع فيه الإجراءات التي لها تأثير شامل على
تطبيقك، مثل "بحث Google" و"إنشاء رسالة إلكترونية" و"الإعدادات".
راجِع قسم إنشاء قائمة خيارات.
- قائمة السياقات ووضع الإجراءات المستندة إلى السياق
- قائمة السياقات هي قائمة عائمة
تظهر عندما يلمس المستخدم عنصرًا ويضغط عليه مع الاستمرار. ويقدّم
إجراءات تؤثّر في المحتوى أو إطار السياق المحدّد.
يعرض وضع الإجراءات السياقية عناصر الإجراءات التي تؤثر في المحتوى المحدّد في شريط في أعلى الشاشة، ويسمح للمستخدم باختيار عناصر متعددة.
راجِع قسم إنشاء قائمة سياقية.
- القائمة المنبثقة
- تعرض القائمة المنبثقة قائمة عمودية بالعناصر المرتبطة بالملف الشخصي
الذي يشغّل القائمة. من الجيد تقديم عدد كبير من الإجراءات
المرتبطة بمحتوى معيّن أو تقديم خيارات للجزء الثاني
من الأمر. لا تؤثّر الإجراءات في القائمة المنبثقة مباشرةً في
محتوى الصفحة المعنيّ، لأنّ هذا هو الغرض من الإجراءات المستندة إلى السياق. بدلاً من ذلك،
هذه القائمة المنبثقة مخصّصة للإجراءات الموسّعة ذات الصلة بمناطق المحتوى في
نشاطك.
راجِع قسم إنشاء قائمة منبثقة.
تحديد قائمة في ملف XML
يقدّم Android تنسيق XML عاديًا لجميع أنواع القوائم لتحديد عناصرها. بدلاً من إنشاء قائمة في رمز نشاطك، حدِّد قائمة
وجميع عناصرها في مرجع قائمة بتنسيق XML. يمكنك
بعد ذلك تضخيم مورد القائمة، أي تحميله كعنصر Menu
في نشاطك أو المقتطف.
يُعدّ استخدام مرجع قائمة طعام ممارسة جيدة للأسباب التالية:
- من الأسهل تصور بنية القائمة بتنسيق XML.
- ويفصل هذا القسم محتوى القائمة عن الرمز البرمجي لسلوك تطبيقك.
- ويتيح لك إنشاء إعدادات قائمة بديلة لإصدارات منصّة مختلفة وأحجام شاشة وإعدادات أخرى من خلال الاستفادة من إطار عمل موارد التطبيق.
لتحديد قائمة طعام، أنشئ ملف XML داخل دليل
res/menu/
في مشروعك وأنشئ القائمة باستخدام العناصر التالية:
<menu>
- تُحدِّد
Menu
، وهي حاوية لعناصر القائمة. يجب أن يكون عنصر<menu>
هو العقدة الجذر للملف، ويمكنه أن يحتوي على عنصر<item>
و<group>
واحد أو أكثر. <item>
- لإنشاء
MenuItem
، الذي يمثّل عنصرًا واحدًا في قائمة. يمكن أن يحتوي هذا العنصر على عنصر<menu>
متداخل لإنشاء قائمة فرعية. <group>
- حاوية اختيارية غير مرئية لعناصر
<item>
تتيح لك هذه الميزة تصنيف عناصر القائمة كي تتشارك الخصائص، مثل الحالة النشطة ومستوى الظهور. لمزيد من المعلومات، يُرجى الاطّلاع على القسم إنشاء مجموعة قوائم الطعام.
في ما يلي مثال على قائمة باسم game_menu.xml
:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/new_game" android:icon="@drawable/ic_new_game" android:title="@string/new_game" app:showAsAction="ifRoom"/> <item android:id="@+id/help" android:icon="@drawable/ic_help" android:title="@string/help" /> </menu>
يتيح العنصر <item>
استخدام عدة سمات يمكنك استخدامها
لتحديد مظهر العنصر وسلوكه. تتضمّن العناصر في القائمة السابقة
السمات التالية:
android:id
- معرّف مورد فريد للعنصر، ما يتيح للتطبيق التعرّف على العنصر عند اختياره من قِبل المستخدم
android:icon
- إشارة إلى عنصر قابل للرسم لاستخدامه كرمز للعنصر
android:title
- مرجع إلى سلسلة لاستخدامها كعنوان للعنصر
android:showAsAction
- مواصفات حالات ظهور هذا العنصر كعنصر إجراء وكيفية ظهوره في شريط التطبيق
هذه هي أهم السمات التي تستخدمها، ولكن هناك العديد من السمات الأخرى المتوفّرة. للحصول على معلومات عن جميع السمات المتوافقة، اطّلِع على مستندات مورد القائمة.
يمكنك إضافة قائمة فرعية إلى عنصر في أي قائمة من خلال إضافة عنصر
<menu>
كعنصر فرعي لعنصر <item>
.
تكون القوائم الفرعية مفيدة عندما يتضمّن تطبيقك الكثير من الوظائف التي يمكن تنظيمها
حسب المواضيع، مثل العناصر في شريط قوائم تطبيق الكمبيوتر الشخصي، مثل ملف
وتعديل وعرض. راجِع المثال التالي:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/file" android:title="@string/file" > <!-- "file" submenu --> <menu> <item android:id="@+id/create_new" android:title="@string/create_new" /> <item android:id="@+id/open" android:title="@string/open" /> </menu> </item> </menu>
لاستخدام القائمة في نشاطك، عليك _تضخيم_ مورد القائمة، وتحويل
مورد XML إلى عنصر قابل للبرمجة باستخدام
MenuInflater.inflate()
.
توضّح الأقسام التالية كيفية تضخيم قائمة لكل نوع من أنواع القوائم.
إنشاء قائمة خيارات
قائمة الخيارات، مثل القائمة الموضّحة في الشكل 1، هي المكان الذي يمكنك فيه تضمين الإجراءات والخيارات الأخرى ذات الصلة بسياق النشاط الحالي، مثل "بحث" و"إنشاء رسالة إلكترونية" و "الإعدادات".
![صورة تعرض شريط التطبيق الخاص بتطبيق "جداول بيانات Google"](https://developer.android.com/static/images/training/appbar/appbar_sheets_2x.png?authuser=0000&hl=ar)
يمكنك الإفصاح عن عناصر لقائمة الخيارات من
Activity
الطبقة الفرعية أو
Fragment
الطبقة الفرعية. إذا كان كلّ من نشاطك وشظاياك يعرِضان عناصر لقائمة
الخيارات، يتم دمج العناصر في واجهة المستخدم. تظهر عناصر النشاط أولاً، ثم عناصر كلّ جزء، وذلك بالترتيب الذي تمت فيه إضافة الأجزاء إلى النشاط. إذا لزم الأمر، يمكنك إعادة ترتيب عناصر القائمة باستخدامسمة android:orderInCategory
في كل<item>
تريد نقله.
لتحديد قائمة الخيارات لنشاط معيّن، يمكنك إلغاء
onCreateOptionsMenu()
.
تقدّم الأجزاء onCreateOptionsMenu()
مكالمة برمجية خاصة بها. في هذه الطريقة، يمكنك توسيع نطاق مرجع القائمة،
الذي تم تحديده في ملف XML، إلى Menu
المقدَّمة في
الاستدعاء. يظهر ذلك في المثال التالي:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.game_menu, menu) return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.game_menu, menu); return true; }
يمكنك أيضًا إضافة عناصر قائمة باستخدام
add()
واسترداد العناصر باستخدام
findItem()
لمراجعة خصائصها باستخدام واجهات برمجة تطبيقات MenuItem
.
التعامل مع أحداث النقر
عندما يختار المستخدم عنصرًا من قائمة الخيارات، بما في ذلك عناصر الإجراءات
في شريط التطبيق، يستدعي النظام onOptionsItemSelected()
طريقة نشاطك. تُرسِل هذه الطريقة MenuItem
المحدّد. يمكنك تحديد
العنصر من خلال استدعاء
getItemId()
،
الذي يعرض المعرّف الفريد لعنصر القائمة، والذي يتم تحديده من خلال سمة
android:id
في مورد القائمة أو باستخدام عدد صحيح يتم تقديمه
لطريقة add()
. يمكنك مطابقة هذا المعرّف مع ملف تعريف
العناصر المعروفة في القائمة لتنفيذ الإجراء المناسب.
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { // Handle item selection. return when (item.itemId) { R.id.new_game -> { newGame() true } R.id.help -> { showHelp() true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection. switch (item.getItemId()) { case R.id.new_game: newGame(); return true; case R.id.help: showHelp(); return true; default: return super.onOptionsItemSelected(item); } }
عند معالجة عنصر قائمة بنجاح، أرسِل القيمة true
. إذا
لم تعالج عنصر القائمة، استخدِم تنفيذ الفئة الأساسية لمحاولة
onOptionsItemSelected()
. يعرض التنفيذ التلقائي قيمة
false.
إذا كان نشاطك يتضمّن أجزاء، يستدعي النظام أولاً
onOptionsItemSelected()
للنشاط، ثم يستدعي كل جزء
بالترتيب الذي تمت به إضافة الأجزاء، إلى أن يعرض أحدها true
أو
يتم استدعاء جميع الأجزاء.
تغيير عناصر القائمة أثناء التشغيل
بعد أن يستدعي النظام onCreateOptionsMenu()
، يحتفظ بأحد
مثيلات Menu
التي تم تعبئتها ولا يستدعي
onCreateOptionsMenu()
مرة أخرى ما لم يتم إلغاء صلاحية القائمة.
ومع ذلك، استخدِم onCreateOptionsMenu()
فقط لإنشاء حالة القائمة
الأولية وليس لإجراء تغييرات أثناء دورة حياة النشاط.
إذا كنت تريد تعديل قائمة الخيارات استنادًا إلى الأحداث التي تحدث أثناء
رحلة النشاط، يمكنك إجراء ذلك في onPrepareOptionsMenu()
الطريقة. تُمرِّر هذه الطريقة عنصر Menu
كما هو عليه
حاليًا حتى تتمكّن من تعديله، مثلاً من خلال إضافة عناصر أو إزالتها أو إيقافها.
توفّر الأجزاء أيضًا onPrepareOptionsMenu()
مكالمة استدعاء.
تُعتبر قائمة الخيارات مفتوحة دائمًا عند عرض عناصر القائمة في
شريط التطبيق. عند حدوث حدث وأردت إجراء تعديل على القائمة، اتصل بالرقم
invalidateOptionsMenu()
لطلب أن يتصل النظام بالرقم onPrepareOptionsMenu()
.
إنشاء قائمة سياقية
![صورة تعرض قائمة سياقات عائمة](https://developer.android.com/static/develop/ui/views/images/context_menu_no_icons.png?authuser=0000&hl=ar)
تقدّم قائمة السياقات إجراءات تؤثّر في عنصر أو إطار سياق معيّن في واجهة المستخدم. يمكنك توفير قائمة سياق لأي عرض، ولكن يتم استخدامها في الغالب
للعناصر في
RecylerView
أو
مجموعات أخرى من طرق العرض التي يمكن للمستخدم فيها تنفيذ إجراءات مباشرة على كل
عنصر.
هناك طريقتان لتقديم الإجراءات المستندة إلى السياق:
- في قائمة سياقات عائمة تظهر القائمة كقائمة عائمة لعناصر القائمة، مثل مربّع حوار، عندما ينفّذ مستخدم لمسة مع الاستمرار على عرض يعلن عن توافقه مع قائمة سياقية. يمكن للمستخدمين تنفيذ إجراء سياقي على عنصر واحد في كل مرة.
- في وضع الإجراءات المستندة إلى السياق هذا الوضع هو أحد ميزات
ActionMode
التي يعرضها النظام في شريط الإجراءات السياقية في أعلى الشاشة، ويتضمن هذا الشريط عناصر الإجراءات التي تؤثر في العناصر المحدّدة. عندما يكون هذا الوضع مفعّلاً، يمكن للمستخدمين تنفيذ إجراء على عناصر متعددة في آنٍ واحد، إذا كان تطبيقك يتيح ذلك.
ملاحظة: لا تتيح قائمة السياقات استخدام اختصارات العناصر ورموزها.
إنشاء قائمة سياقات عائمة
لتقديم قائمة سياق عائمة، اتّبِع الخطوات التالية:
- سجِّل
View
المرتبط بقائمة السياقات من خلال الاتصالregisterForContextMenu()
ونقْلView
إليه.إذا كان نشاطك يستخدم
RecyclerView
وأردت أن يقدّم كل عنصر قائمة السياق نفسها، سجِّل جميع العناصر لقائمة سياق من خلال تمريرRecyclerView
إلىregisterForContextMenu()
. - نفِّذ
onCreateContextMenu()
Activity
أوFragment
.عندما يتلقّى العرض المسجَّل حدث لمس مع الاستمرار، يستدعي النظام طريقة
onCreateContextMenu()
. يمكنك هنا تحديد عناصر القائمة، عادةً من خلال تضخيم مورد قائمة، كما هو موضّح في المثال التالي:Kotlin
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) { super.onCreateContextMenu(menu, v, menuInfo) val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.context_menu, menu) }
Java
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); }
MenuInflater
يتيح لك هذا العنصر تضخيم قائمة السياقات من مورد قائمة. تتضمّن مَعلمات أسلوب callback العنصرView
الذي يختاره المستخدم وموضوعContextMenu.ContextMenuInfo
الذي يقدّم معلومات إضافية عن العنصر المحدّد. إذا كان نشاطك يتضمّن عدة طرق عرض يقدّم كلّ منها قائمة سياقات مختلفة، يمكنك استخدام هذه المَعلمات لتحديد قائمة السياقات التي تريد توسيعها. نفِّذ
onContextItemSelected()
، كما هو موضّح في المثال التالي. عندما يختار المستخدم عنصر قائمة، يُطلِق نظام التشغيل هذه الطريقة لتتمكّن من تنفيذ الإجراء المناسب.Kotlin
override fun onContextItemSelected(item: MenuItem): Boolean { val info = item.menuInfo as AdapterView.AdapterContextMenuInfo return when (item.itemId) { R.id.edit -> { editNote(info.id) true } R.id.delete -> { deleteNote(info.id) true } else -> super.onContextItemSelected(item) } }
Java
@Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case R.id.edit: editNote(info.id); return true; case R.id.delete: deleteNote(info.id); return true; default: return super.onContextItemSelected(item); } }
تبحث طريقة
getItemId()
عن رقم تعريف عنصر القائمة المحدّد، والذي تحدّده لكل عنصر قائمة في ملف XML باستخدام سمةandroid:id
، كما هو موضّح في تحديد قائمة في ملف XML.عند معالجة عنصر قائمة بنجاح، أرسِل القيمة
true
. إذا لم تعالج عنصر القائمة، مرِّر عنصر القائمة إلى تنفيذ الدرجة العليا من الفئة. إذا كان نشاطك يتضمّن أجزاء، يتلقّى النشاط هذا المرجع إلى دالة الربط أولاً. من خلال استدعاء الفئة الفائقة عند عدم معالجتها، يُحيل النظام الحدث إلى طريقة الاستدعاء ذات الصلة في كل جزء، واحدًا تلو الآخر ، بترتيب إضافة كل جزء، إلى أن يتم عرضtrue
أوfalse
. تُعرِض عمليات التنفيذ التلقائية لمحاولةActivity
وandroid.app.Fragment
القيمةfalse
، لذا يجب دائمًا استدعاء الفئة الفائقة عند عدم معالجتها.
استخدام وضع الإجراءات المستندة إلى السياق
وضع الإجراءات المستندة إلى السياق هو تنفيذ برمجي لميزة
ActionMode
التي تركّز تفاعل المستخدم على تنفيذ
الإجراءات المستندة إلى السياق. عندما يفعّل المستخدم هذا الوضع من خلال اختيار عنصر، يظهر
شريط إجراءات سياقي في أعلى الشاشة لعرض
الإجراءات التي يمكن للمستخدم تنفيذها على العناصر المحدّدة. عندما يكون هذا الوضع مفعّلاً،
يمكن للمستخدم اختيار عناصر متعدّدة، إذا كان تطبيقك يتيح ذلك، ويمكنه إلغاء اختيار
العناصر ومواصلة التنقّل في النشاط. يكون وضع الإجراءات غير مفعَّل ويختفي شريط الإجراءات السياقية عندما يلغِي المستخدم اختيار جميع العناصر أو ينقر على الزر "رجوع" أو ينقر على الإجراء تم على الجانب الأيسر من العارض.
بالنسبة إلى المشاهد التي توفّر إجراءات مستندة إلى السياق، يتم عادةً تفعيل وضع الإجراءات المستندة إلى السياق عند حدوث أحد هذين الحدثَين أو كليهما:
- يضغط المستخدم مع الاستمرار على العرض.
- يختار المستخدم مربّع اختيار أو مكوّن واجهة مستخدم مشابهًا ضمن طريقة العرض.
تعتمد طريقة تطبيقك في استدعاء وضع الإجراءات السياقية وتحديد السلوك لكل إجراء على تصميمك. هناك تصميمان:
- للإجراءات السياقية على مشاهدات فردية عشوائية
- للإجراءات السياقية المجمّعة على مجموعات من العناصر في
RecyclerView
، ما يتيح للمستخدم اختيار عناصر متعددة وتنفيذ إجراء عليها جميعًا.
توضّح الأقسام التالية الإعدادات المطلوبة للسيناريو الأول.
تفعيل وضع الإجراءات المستندة إلى السياق لعروض فردية
إذا كنت تريد تفعيل وضع الإجراءات المستندة إلى السياق فقط عندما يختار المستخدِم طرق عرض معيّنة، اتّبِع الخطوات التالية:
- نفِّذ واجهة
ActionMode.Callback
كما هو موضّح في المثال التالي: في طرق الاستدعاء، يمكنك تحديد الإجراءات المتعلّقة بشريط الإجراءات السياقية، والردّ على أحداث النقر على عناصر الإجراءات، ومعالجة أحداث دورة الحياة الأخرى لوضع الإجراءات.Kotlin
private val actionModeCallback = object : ActionMode.Callback { // Called when the action mode is created. startActionMode() is called. override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { // Inflate a menu resource providing context menu items. val inflater: MenuInflater = mode.menuInflater inflater.inflate(R.menu.context_menu, menu) return true } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { return false // Return false if nothing is done } // Called when the user selects a contextual menu item. override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_share -> { shareCurrentItem() mode.finish() // Action picked, so close the CAB. true } else -> false } } // Called when the user exits the action mode. override fun onDestroyActionMode(mode: ActionMode) { actionMode = null } }
Java
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() { // Called when the action mode is created. startActionMode() is called. @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items. MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); return true; } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done. } // Called when the user selects a contextual menu item. @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.menu_share: shareCurrentItem(); mode.finish(); // Action picked, so close the CAB. return true; default: return false; } } // Called when the user exits the action mode. @Override public void onDestroyActionMode(ActionMode mode) { actionMode = null; } };
إنّ وظائف الاستدعاء هذه للأحداث متطابقة تقريبًا مع وظائف الاستدعاء ل قائمة الخيارات، باستثناء أنّ كلّ واحدة من هذه الوظائف تُمرِّر أيضًا عنصر
ActionMode
المرتبط بالحدث. يمكنك استخدام واجهات برمجة التطبيقاتActionMode
لإجراء تغييرات مختلفة على CAB، مثل مراجعة العنوان والعنوان الفرعي باستخدامsetTitle()
وsetSubtitle()
، وهو أمر مفيد للإشارة إلى عدد العناصر المحدّدة.يضبط النموذج السابق المتغيّر
actionMode
علىnull
عند إتلاف وضع الإجراء. في الخطوة التالية، اطّلِع على كيفية إعداده وكيفية حفظ المتغيّر العضو في نشاطك أو القسم. - اتصل
startActionMode()
عندما تريد عرض الشريط، مثلاً عندما يلمس المستخدم الشاشة ويشدِّد على اللمس في العرض.Kotlin
someView.setOnLongClickListener { view -> // Called when the user performs a touch & hold on someView. when (actionMode) { null -> { // Start the CAB using the ActionMode.Callback defined earlier. actionMode = activity?.startActionMode(actionModeCallback) view.isSelected = true true } else -> false } }
Java
someView.setOnLongClickListener(new View.OnLongClickListener() { // Called when the user performs a touch & hold on someView. public boolean onLongClick(View view) { if (actionMode != null) { return false; } // Start the CAB using the ActionMode.Callback defined earlier. actionMode = getActivity().startActionMode(actionModeCallback); view.setSelected(true); return true; } });
عند استدعاء
startActionMode()
، يعرض النظامActionMode
الذي تم إنشاؤه. من خلال حفظ هذا الإجراء في متغيّر عضو، يمكنك إجراء تغييرات على شريط الإجراءات السياقية استجابةً لأحداث أخرى. في العيّنة السابقة، يتم استخدامActionMode
لضمان عدم إعادة إنشاء مثيلActionMode
إذا كان مفعّلاً، وذلك من خلال التحقّق مما إذا كان العنصر فارغًا قبل بدء وضع الإجراء.
إنشاء قائمة منبثقة
![صورة تعرض قائمة منبثقة في تطبيق Gmail، تم تثبيتها على زر القائمة الكاملة في أعلى يسار الصفحة](https://developer.android.com/static/images/ui/popupmenu.png?authuser=0000&hl=ar)
PopupMenu
هي قائمة وضع نوافذ مشروطة مرتبطة بعنصر View
. يظهر أسفل العنصر المرتبط
العرض إذا كانت هناك مساحة، أو فوق العرض في حال عدم توفّر مساحة. وهي مفيدة في ما يلي:
- توفير قائمة بأسلوب القائمة المنسدلة للإجراءات التي ترتبط بمحتوى معيّن، مثل رؤوس الرسائل الإلكترونية في Gmail، كما هو موضّح في الشكل 4
- تقديم جزء ثانٍ من جملة الأمر، مثل زر يحمل العلامة إضافة يعرض قائمة منبثقة تتضمّن خيارات مختلفة لالإضافة
- توفير قائمة مشابهة لرمز
Spinner
لا تحتفظ باختيار دائم
إذا كنت تحدّد قائمتك بتنسيق XML، إليك كيفية عرض القائمة المنبثقة:
- أنشئ مثيلًا لعنصر
PopupMenu
باستخدام وظيفته المُنشئة التي تأخذContext
التطبيق الحاليView
وView
الذي تم تثبيت القائمة عليه. - استخدِم
MenuInflater
لتضخيم مورد القائمة في عنصرMenu
الذي يعرضهPopupMenu.getMenu()
. - الاتصال بالرقم
PopupMenu.show()
.
على سبيل المثال، إليك زر يعرض قائمة منبثقة:
<ImageButton android:id="@+id/dropdown_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/descr_overflow_button" android:src="@drawable/arrow_drop_down" />
يمكن للنشاط بعد ذلك عرض القائمة المنبثقة على النحو التالي:
Kotlin
findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener { val popup = PopupMenu(this, it) val inflater: MenuInflater = popup.menuInflater inflater.inflate(R.menu.actions, popup.menu) popup.show() }
Java
findViewById(R.id.dropdown_menu).setOnClickListener(v -> { PopupMenu popup = new PopupMenu(this, v); popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu()); popup.show(); });
يتم إغلاق القائمة عندما يختار المستخدم عنصرًا أو ينقر خارج منطقة
القائمة. يمكنك الاستماع إلى حدث الإغلاق باستخدام
PopupMenu.OnDismissListener
.
التعامل مع أحداث النقر
لتنفيذ إجراء عندما يختار المستخدم عنصرًا من القائمة، نفِّذ واجهة
PopupMenu.OnMenuItemClickListener
واسجِّلها في PopupMenu
من خلال استدعاء
setOnMenuItemclickListener()
.
عندما يختار المستخدم عنصرًا، يستدعي النظام onMenuItemClick()
دالة الاستدعاء في واجهتك.
يظهر ذلك في المثال التالي:
Kotlin
fun showMenu(v: View) { PopupMenu(this, v).apply { // MainActivity implements OnMenuItemClickListener. setOnMenuItemClickListener(this@MainActivity) inflate(R.menu.actions) show() } } override fun onMenuItemClick(item: MenuItem): Boolean { return when (item.itemId) { R.id.archive -> { archive(item) true } R.id.delete -> { delete(item) true } else -> false } }
Java
public void showMenu(View v) { PopupMenu popup = new PopupMenu(this, v); // This activity implements OnMenuItemClickListener. popup.setOnMenuItemClickListener(this); popup.inflate(R.menu.actions); popup.show(); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.archive: archive(item); return true; case R.id.delete: delete(item); return true; default: return false; } }
إنشاء مجموعة قوائم طعام
مجموعة القوائم هي مجموعة من عناصر القائمة التي تتشارك سمات معيّنة. باستخدام المجموعة، يمكنك إجراء ما يلي:
- يمكنك إظهار جميع العناصر أو إخفاؤها باستخدام
setGroupVisible()
. - فعِّل كل العناصر أو أوقِفها باستخدام
setGroupEnabled()
. - حدِّد ما إذا كان بإمكان المستخدمين وضع علامة في المربّعات بجانب كل العناصر باستخدام رمز
setGroupCheckable()
.
يمكنك إنشاء مجموعة من خلال إدراج عناصر <item>
داخل
عنصر <group>
في مورد القائمة أو من خلال تحديد
معرّف مجموعة باستخدام الأسلوب
add()
.
في ما يلي مثال على مورد قائمة يتضمّن مجموعة:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_save" android:icon="@drawable/menu_save" android:title="@string/menu_save" /> <!-- menu group --> <group android:id="@+id/group_delete"> <item android:id="@+id/menu_archive" android:title="@string/menu_archive" /> <item android:id="@+id/menu_delete" android:title="@string/menu_delete" /> </group> </menu>
تظهر العناصر في المجموعة على المستوى نفسه الذي يظهر به العنصر
الأول، وجميع العناصر الثلاثة في القائمة هي عناصر متسلسلة. ومع ذلك، يمكنك تعديل
سمات السلعتَين في المجموعة من خلال الإشارة إلى معرّف المجموعة واستخدام
الطرق السابقة. ولا يفصل النظام أبدًا العناصر المجمّعة. على سبيل المثال، إذا أعلنت عن android:showAsAction="ifRoom"
لكل
عنصر، سيظهر كلاهما في شريط الإجراءات أو في overflow
الإجراء.
استخدام عناصر قائمة يمكن وضع علامة عليها
يمكن أن تكون القائمة مفيدة كواجهة لتفعيل الخيارات وإيقافها، وذلك باستخدام مربّع اختيار للخيارات المستقلة أو أزرار اختيار لمجموعات من الخيارات المشترَكة. يعرض الشكل 5 قائمة فرعية تحتوي على عناصر يمكن وضع علامة عليها باستخدام buttonsradio buttons.
يمكنك تحديد السلوك الذي يمكن التحكّم فيه لعناصر قائمة فردية باستخدام سمة
android:checkable
في العنصر <item>
، أو لمجموعة كاملة باستخدام سمة android:checkableBehavior
في العنصر <group>
. على سبيل المثال، يمكن وضع علامة في المربّع بجانب كل العناصر في
مجموعة القوائم هذه باستخدام زر اختيار:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/red" android:title="@string/red" /> <item android:id="@+id/blue" android:title="@string/blue" /> </group> </menu>
تقبل السمة android:checkableBehavior
أحد العناصر التالية:
single
- يمكن وضع علامة في عنصر واحد فقط من المجموعة، ما يؤدي إلى استخدام مفاتيح اختيار.
all
- يمكن وضع علامة في كل العناصر، ما يؤدي إلى ظهور مربّعات اختيار.
none
- لا يمكن وضع علامة في المربّع بجانب أي عناصر.
يمكنك تطبيق حالة محدَّدة تلقائيًا على عنصر باستخدام سمة
android:checked
في العنصر <item>
وتغييرها في الرمز باستخدام الطريقة
setChecked()
.
عند اختيار عنصر قابل للتحقّق، يستدعي النظام أسلوب callback المرتبط بالعنصر، مثل onOptionsItemSelected()
.
يمكنك هنا ضبط حالة مربّع الاختيار، لأنّ مربّع الاختيار أو زر الاختيار المبرمَج لا يغيّر حالته تلقائيًا. يمكنك الاستعلام عن الحالة الحالية
للعنصر، كما كانت قبل أن يختارها المستخدم، باستخدام
isChecked()
ثم ضبط الحالة التي تم وضع علامة عليها باستخدام setChecked()
. يظهر ذلك في المثال التالي:
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.vibrate, R.id.dont_vibrate -> { item.isChecked = !item.isChecked true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.vibrate: case R.id.dont_vibrate: if (item.isChecked()) item.setChecked(false); else item.setChecked(true); return true; default: return super.onOptionsItemSelected(item); } }
في حال عدم ضبط الحالة التي تم وضع علامة فيها بهذه الطريقة، لن تتغيّر الحالة المرئية لصندوق الاختيار أو زر الاختيار عندما يختار المستخدم أحدهما. عند تحديد الحالة، يحافظ النشاط على حالة الاختيار للعنصر لكي تتمكّن من رؤية الحالة التي حدّدتها عند فتح المستخدم للقائمة لاحقًا.
إضافة عناصر قائمة استنادًا إلى نية
في بعض الأحيان، تريد أن يؤدي عنصر قائمة إلى تشغيل نشاط باستخدام Intent
، سواء كان نشاطًا في تطبيقك أو تطبيقًا آخر. عندما تعرف النيّة التي تريد استخدامها ويكون لديك عنصر قائمة محدّد يشغّل النيّة، يمكنك تنفيذ النيّة باستخدام startActivity()
أثناء طريقة الاستدعاء المناسبة التي تم اختيارها حسب العنصر، مثل onOptionsItemSelected()
.
ومع ذلك، إذا لم تكن متأكدًا من أنّ جهاز المستخدم يحتوي على تطبيق يعالج النية، قد تؤدي إضافة عنصر قائمة يشغّله إلى عدم معالجة العنصر، لأنّ النية قد لا تؤدي إلى نشاط. لحلّ هذه المشكلة، يتيح لك Android إضافة عناصر قائمة ديناميكيًا إلى قائمتك عندما يرصد Android أنشطة على الجهاز تعالج طلبك.
لإضافة عناصر قائمة استنادًا إلى الأنشطة المتاحة التي تقبل نية، اتّبِع الخطوات التالية:
- حدِّد نية باستخدام الفئة
CATEGORY_ALTERNATIVE
أوCATEGORY_SELECTED_ALTERNATIVE
، أو كليهما، بالإضافة إلى أي متطلبات أخرى. - يُرجى الاتصال بالرقم
Menu.addIntentOptions()
. بعد ذلك، يبحث Android عن أي تطبيقات يمكنها تنفيذ الطلب ويُعدِّلها ويُضيفها إلى قائمتك.
إذا لم تكن هناك تطبيقات مثبَّتة تستوفي الطلب، لن تتم إضافة أي ملف شخصي في القائمة.
يظهر ذلك في المثال التالي:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. val intent = Intent(null, dataUri).apply { addCategory(Intent.CATEGORY_ALTERNATIVE) } // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.componentName, // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null) // Array of MenuItems that correlate to specific items (none). return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. Intent intent = new Intent(null, dataUri); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.getComponentName(), // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null); // Array of MenuItems that correlate to specific items (none). return true; }
بالنسبة إلى كل نشاط تم العثور عليه ويقدّم فلتر نية يتطابق مع النيّة
المحدّدة، تتم إضافة عنصر قائمة باستخدام القيمة في android:label
لفلتر النيّة كعنوان لعنصر القائمة ورمز التطبيق كرمز لعنصر
القائمة. تُعرِض الطريقة addIntentOptions()
عدد
عناصر القائمة التي تمت إضافتها.
السماح بإضافة نشاطك إلى قوائم أخرى
يمكنك تقديم خدمات نشاطك التجاري إلى تطبيقات أخرى حتى يتم تضمين تطبيقك في قائمة التطبيقات الأخرى، ما يؤدي إلى عكس الأدوار الموضّحة سابقًا.
لتضمين التطبيق في قوائم التطبيقات الأخرى، حدِّد فلتر أهداف كالمعتاد،
ولكن أدرِج القيم CATEGORY_ALTERNATIVE
أو
CATEGORY_SELECTED_ALTERNATIVE
أو كليهما لفئة
فلتر الأهداف. يظهر ذلك في المثال التالي:
<intent-filter label="@string/resize_image"> ... <category android:name="android.intent.category.ALTERNATIVE" /> <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> ... </intent-filter>
اطّلِع على مزيد من المعلومات عن كتابة فلاتر الأهداف في مقالة الأهداف وفلاتر الأهداف.