إضافة قوائم

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

القوائم هي عنصر واجهة مستخدم شائع في العديد من أنواع التطبيقات. إلى تجربة مستخدم مألوفة ومتسقة، واستخدام Menu واجهات برمجة تطبيقات إلى وتقديم إجراءات المستخدم والخيارات الأخرى في أنشطتك.

صورة تعرض مثالاً على القائمة الكاملة
الشكل 1. ستظهر قائمة يتم تشغيلها بالنقر على الأيقونة، أسفل أيقونة القائمة الكاملة.

يوضح هذا المستند كيفية إنشاء الأنواع الأساسية الثلاثة من القوائم أو عروض تقديمية للإجراءات على جميع إصدارات Android:

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

الاطّلاع على إنشاء قائمة خيارات .

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

يعرض وضع الإجراءات المستندة إلى السياق بنود العمل التي للتأثير في المحتوى المحدد في شريط أعلى الشاشة ويسمح تحديد المستخدم عناصر متعددة.

يمكنك الاطّلاع على مقالة إنشاء قائمة سياقية. .

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

راجِع القسم إنشاء قائمة منبثقة.

تحديد قائمة في ملف 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، هي المكان الذي تقوم فيه بتضمين الإجراءات والخيارات الأخرى ذات الصلة بسياق النشاط الحالي، مثل "البحث" "إنشاء بريد إلكتروني"، و"الإعدادات".

صورة تعرض شريط التطبيقات الخاص بتطبيق &quot;جداول بيانات Google&quot;
الشكل 2. يعرض تطبيق Google Sheets عدة أزرار، بما في ذلك زر القائمة الكاملة للإجراء.

يمكنك الإعلان عن عناصر لقائمة الخيارات من 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() تُرجع عملية التنفيذ التلقائية خطأ.

إذا كان نشاطك يتضمّن أجزاءً، يستدعي النظام أولاً onOptionsItemSelected() للنشاط، ثم لكل جزء بترتيب إضافة الأجزاء، حتى تعرض إحداها true أو بحيث يتم استدعاء جميع الأجزاء.

تغيير عناصر القائمة في وقت التشغيل

بعد استدعاء النظام لـ onCreateOptionsMenu()، يحتفظ بـ مثيل Menu الذي تقوم بتعبئته ولا تستدعيه onCreateOptionsMenu() مجددًا ما لم يتم إلغاء صلاحية القائمة. ومع ذلك، يمكنك استخدام onCreateOptionsMenu() لإنشاء القائمة الأولية فقط. وعدم إجراء تغييرات أثناء دورة حياة النشاط.

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

تُعد قائمة الخيارات مفتوحة دائمًا عند عرض عناصر القائمة في شريط التطبيق. وعندما يقع الحدث وتريد إجراء تحديث للقائمة، اتصل invalidateOptionsMenu() لطلب استدعاء النظام لـ onPrepareOptionsMenu().

إنشاء قائمة سياقية

صورة تعرض قائمة سياقات عائمة
الشكل 3. قائمة سياق عائمة

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

هناك طريقتان لتقديم الإجراءات المستندة إلى السياق:

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

ملاحظة: لا تتيح قائمة السياقات استخدام اختصارات العناصر ورموز العناصر.

إنشاء قائمة سياق عائمة

لتوفير قائمة سياق عائمة، اتّبِع الخطوات التالية:

  1. يمكنك تسجيل View التي ترتبط بها قائمة السياق من خلال يتصل registerForContextMenu() وتمريره View.

    إذا كان نشاطك يستخدم "RecyclerView" وكنت تريد كل منتج لتوفير قائمة السياقات نفسها، وتسجيل جميع العناصر للحصول على سياق القائمة من خلال تمرير RecyclerView إلى registerForContextMenu()

  2. نفِّذ 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 يوفر معلومات إضافية حول العنصر المحدد. في حال حذف نشاطك له عدة طرق عرض يوفر كل منها قائمة سياق مختلفة، يمكنك استخدام هذه المعلمات لتحديد أي قائمة سياقات وتضخيم.

  3. التنفيذ 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، مما يتيح للمستخدم اختيار عناصر متعددة لتنفيذ إجراء عليها جميعًا.

تصف الأقسام التالية الإعداد المطلوب لكل سيناريو.

تفعيل وضع الإجراءات المستندة إلى السياق في مشاهدات فردية

إذا كنت تريد استدعاء وضع الإجراء المستند إلى السياق فقط عندما يختار المستخدم طرق عرض محددة، قم بما يلي:

  1. نفِّذ واجهة 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 عندما يكون وضع الإجراء تالفًا. في الخطوة التالية، راجع وكيف يتم إعداده وكيف يتم حفظ المتغير العضو في نشاطك أو يمكن أن يكون الجزء مفيدًا.

  2. اتصل 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، تظهر في أعلى يسار الشاشة بزر القائمة الكاملة.
الشكل 4. ستظهر قائمة منبثقة في تطبيق Gmail مثبّتًا على زر القائمة الكاملة في أعلى يسار الشاشة

PopupMenu هي قائمة مشروطة تستند إلى View. ويظهر أسفل علامة الارتساء لمعرفة ما إذا كان هناك مساحة، أو أعلى من العرض. إنها مفيدة التالي:

  • توفير قائمة بنمط كامل للإجراءات التي تتعلق بـ لمحتوى معين، مثل رؤوس البريد الإلكتروني في Gmail، كما هو موضح في الشكل 4.
  • تقديم جزء ثانٍ من جملة أوامر، مثل زر موضوع عليه علامة الإضافة التي تؤدي إلى إنشاء قائمة منبثقة تتضمن دالة إضافة مختلفة الخيارات.
  • يمكن أن يضمن توفير قائمة مشابهة Spinner لا يحتفظ بتحديد دائم.

إذا حدَّدت قائمتك بتنسيق XML، إليك كيفية عرض القائمة المنبثقة:

  1. يمكن إنشاء مثيل لـ PopupMenu باستخدام الدالة الإنشائية التي تتخذ التطبيق الحالي Context و View التي ترتبط بها القائمة.
  2. استخدِم MenuInflater لتوسيع نطاق موارد القائمة إلى تم عرض عنصر Menu بواسطة PopupMenu.getMenu()
  3. الاتصال بالرقم 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" لكلّ العنصر، يظهر كلاهما في شريط الإجراءات أو يظهر كلاهما في الإجراء تجاوز.

استخدام عناصر القائمة القابلة للتحديد

الشكل 5. قائمة فرعية تحتوي التي يمكن وضع علامة عليها

يمكن أن تكون القائمة مفيدة كواجهة لتشغيل الخيارات وإيقافها، باستخدام مربع اختيار للخيارات المستقلة أو أزرار الاختيار للمجموعات والخيارات الحصرية. يعرض الشكل 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 على الأنشطة التي تحقّق هدفك على الجهاز.

لإضافة عناصر في القائمة بناءً على الأنشطة المتاحة التي تقبل النية بالشراء، اتّبِع الخطوات التالية: ما يلي:

  1. تحديد هدف من الفئة CATEGORY_ALTERNATIVE أو CATEGORY_SELECTED_ALTERNATIVE, أو كليهما، بالإضافة إلى أي متطلبات أخرى.
  2. اتصل 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>

مزيد من المعلومات حول كتابة فلاتر الأهداف باللغة النوايا والنيّة من عملية الشراء والفلاتر.