القوائم هي عنصر شائع لواجهة المستخدم في العديد من أنواع التطبيقات. لتوفير
تجربة مستخدم مألوفة ومتسقة، استخدم
واجهات برمجة تطبيقات
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>
لاستخدام القائمة في نشاطك، _inflate_، ثم حوِّل مورد XML إلى كائن قابل للبرمجة باستخدام MenuInflater.inflate()
.
توضّح الأقسام التالية كيفية تضخيم قائمة لكل نوع من أنواع القوائم.
إنشاء قائمة خيارات
قائمة الخيارات، مثل القائمة التي تظهر في الشكل 1، هي المكان الذي يمكنك فيه تضمين الإجراءات والخيارات الأخرى ذات الصلة بسياق النشاط الحالي، مثل "بحث" و"إنشاء بريد إلكتروني" و "الإعدادات".
![صورة تعرض شريط التطبيق الخاص بتطبيق "جداول بيانات Google"](https://developer.android.com/static/images/training/appbar/appbar_sheets_2x.png?authuser=5&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()
.
إنشاء قائمة سياقية
تقدم القائمة السياقية إجراءات تؤثر على عنصر معين أو إطار سياق
في واجهة المستخدم. يمكنك توفير قائمة سياق لأي طريقة عرض، ولكن غالبًا ما يتم استخدامها للعناصر في RecylerView
أو مجموعات طرق العرض الأخرى التي يمكن للمستخدم من خلالها تنفيذ إجراءات مباشرة على كل عنصر.
هناك طريقتان لتوفير الإجراءات السياقية:
- في قائمة سياقات عائمة. تظهر القائمة كقائمة عائمة لعناصر القائمة، مثل مربّع الحوار، عندما يجري المستخدم لمسة مع الاستمرار على عرض يوضح إتاحة قائمة السياق. يمكن للمستخدمين تنفيذ إجراء سياقي على عنصر واحد في كل مرة.
- في وضع الإجراءات المستندة إلى السياق هذا الوضع هو تنفيذ نظام من أجل
ActionMode
يعرض شريط إجراءات سياقية أو CAB في أعلى الشاشة مع بنود عمل تؤثر في العناصر المحددة. عندما يكون هذا الوضع مفعَّلاً، يمكن للمستخدمين تنفيذ إجراء على عناصر متعددة في آنٍ واحد، إذا كان تطبيقك يتيح ذلك.
إنشاء قائمة سياق عائمة
لتوفير قائمة سياق عائمة، اتّبِع الخطوات التالية:
- يمكنك تسجيل
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
تضخيم قائمة السياقات من مورد القائمة. وتتضمّن مَعلمات طريقة معاودة الاتصال السمة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=5&hl=ar)
PopupMenu
هي قائمة نمطية مرتبطة بعنصر View
. ويظهر أسفل شاشة الارتساء إذا كان هناك مساحة، أو أعلى العرض. وهي مفيدة لما يلي:
- توفير قائمة ذات نمط كامل للإجراءات التي تتعلق بمحتوى معيّن، مثل عناوين البريد الإلكتروني في Gmail، الموضحة في الشكل 4
- تقديم جزء ثانٍ من جملة أمر، مثل زرّ يحمل علامة إضافة، ويؤدي إلى إنشاء قائمة منبثقة تتضمّن خيارات إضافة مختلفة
- توفير قائمة مشابهة لـ
Spinner
بدون الاحتفاظ باختيار دائم.
إذا حدِّدت قائمتك بتنسيق XML، إليك كيفية عرض القائمة المنبثقة:
- يمكنك إنشاء مثيل
PopupMenu
باستخدام الدالة الإنشائية التي تأخذ التطبيق الحاليContext
والرمز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 قائمة فرعية بالعناصر التي يمكن التحقق منها باستخدام أزرار الاختيار.
يمكنك تحديد السلوك القابل للتدقيق في عناصر القائمة الفردية باستخدام السمة
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()
.
عند اختيار عنصر قابل للتحديد، يطلب النظام طريقة معاودة الاتصال التي تم اختيارها من خلال عنصر محدّد، مثل 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>
يمكنك قراءة المزيد عن كتابة فلاتر الأهداف في فلاتر الأهداف والغايات.