استخدام AppBar

شريط التطبيق العلوي مكانًا ثابتًا في أعلى نافذة التطبيق لعرض المعلومات والإجراءات من الشاشة الحالية.

مثال على شريط التطبيق العلوي
الشكل 1. مثال على شريط التطبيق العلوي

تختلف ملكية شريط التطبيق حسب احتياجات تطبيقك. فعندما باستخدام الأجزاء، يمكن تنفيذ شريط التطبيق ActionBar يملكه من خلال نشاط المضيف أو شريط الأدوات داخل تنسيق الجزء.

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

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

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

تشير الأمثلة في هذا الموضوع إلى ExampleFragment يحتوي على ملف شخصي قابل للتعديل. يزيد الجزء ما يلي قائمة XML المعرَّفة في شريط التطبيق:

<!-- sample_menu.xml -->
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ic_settings"
        android:title="@string/settings"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_done"
        android:icon="@drawable/ic_done"
        android:title="@string/done"
        app:showAsAction="ifRoom|withText"/>

</menu>

تحتوي القائمة على خيارَين: أحدهما للانتقال إلى شاشة الملف الشخصي وواحدة لحفظ أي تغييرات تم إجراؤها في الملف الشخصي.

شريط التطبيقات المملوك للنشاط

يمتلك شريط التطبيقات في الغالب نشاط المضيف. عند التطبيق شريط يملكه نشاط، ويمكن للأجزاء التفاعل مع شريط التطبيق بتجاوز طرق إطار العمل التي يتم استدعاؤها أثناء إنشاء الأجزاء.

التسجيل باستخدام النشاط

يجب إبلاغ النظام بأنّ جزءًا من شريط التطبيق مشارك. في عدد سكان قائمة الخيارات. للقيام بذلك، اتصل setHasOptionsMenu(true) في طريقة onCreate(Bundle) للجزء كما هو موضح في ما يلي مثال:

Kotlin

class ExampleFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }
}

Java

public class ExampleFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
}

يخبر setHasOptionsMenu(true) النظام أن الجزء يريد تلقي استدعاءات ذات صلة بالقائمة. عندما يتعلق الأمر بالقائمة وقوع الحدث، مثل النقرة، فإن طريقة التعامل مع الحدث تم استدعاء النشاط لأول مرة قبل أن يتم استدعاؤه على الجزء.

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

توسيع القائمة

لدمج قائمتك في قائمة خيارات شريط التطبيق، عليك إلغاء onCreateOptionsMenu() في الجزء. تتلقى هذه الطريقة قائمة شريط التطبيق الحالية MenuInflater كمَعلمات استخدام تضخيم القائمة لإنشاء مثيل لقائمة الأجزاء، ثم ودمجها في القائمة الحالية، كما هو موضح في المثال التالي:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.sample_menu, menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
       inflater.inflate(R.menu.sample_menu, menu);
    }
}

يعرض الشكل 2 القائمة المحدثة.

تحتوي قائمة الخيارات الآن على جزء القائمة
الشكل 2. تحتوي قائمة الخيارات الآن على قائمتك الأجزاء.

التعامل مع الأحداث الناتجة عن النقر

يمكن أن يؤدي كل نشاط وجزء مُشارِك في قائمة الخيارات إلى والاستجابة لللمسات. الجزء onOptionsItemSelected() استلام عنصر القائمة المحدد كمعلمة وعرض قيمة منطقية للإشارة إلى ما إذا كان قد تم استهلاك اللمسة. بمجرد يعرض النشاط أو الجزء true من onOptionsItemSelected()، لا وتتلقى الأجزاء المشاركة الأخرى معاودة الاتصال.

في تنفيذ onOptionsItemSelected()، يمكنك استخدام switch على itemId لعنصر القائمة. إذا كان العنصر المحدد ملكك، لذا تعامل مع اللمس بشكل مناسب وأعِد عرض true للإشارة إلى أنه يتم التعامل مع حدث النقر. إذا لم يكن العنصر المحدد الذي يخصّك، اتّصِل بعملية التنفيذ super. بشكل تلقائي، super تؤدي عملية التنفيذ إلى إرجاع false للسماح بمتابعة معالجة القائمة.

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> {
                // Navigate to settings screen.
                true
            }
            R.id.action_done -> {
                // Save profile changes.
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:  {
                // Navigate to settings screen.
                return true;
            }
            case R.id.action_done: {
                // Save profile changes.
                return true;
            }
            default:
                return super.onOptionsItemSelected(item);
        }

    }

}

تعديل القائمة ديناميكيًا

عليك وضع المنطق لإخفاء زر أو إظهاره أو تغيير الرمز onPrepareOptionsMenu() يتم استدعاء هذه الطريقة مباشرة قبل عرض القائمة.

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

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onPrepareOptionsMenu(menu: Menu){
        super.onPrepareOptionsMenu(menu)
        val item = menu.findItem(R.id.action_done)
        item.isVisible = isEditing
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onPrepareOptionsMenu(@NonNull Menu menu) {
        super.onPrepareOptionsMenu(menu);
        MenuItem item = menu.findItem(R.id.action_done);
        item.setVisible(isEditing);
    }
}

عند الحاجة إلى تحديث القائمة، مثلاً عندما يضغط المستخدم على زر تعديل لتعديل معلومات الملف الشخصي: مكالمة invalidateOptionsMenu() في نشاط المضيف لمطالبة النظام بالاتصال بـ onCreateOptionsMenu(). وبعد إبطاله، يمكنك إجراء التعديلات في "onCreateOptionsMenu()". مرة واحدة يتم تضخيم القائمة، يطلب النظام onPrepareOptionsMenu() ويجري التحديثات القائمة لإظهار الحالة الحالية للجزء.

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateOptionsMenu() {
        isEditing = !isEditing
        requireActivity().invalidateOptionsMenu()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateOptionsMenu() {
        isEditing = !isEditing;
        requireActivity().invalidateOptionsMenu();
    }
}

شريط التطبيقات الذي يملكه جزء من الصفحة

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

<androidx.appcompat.widget.Toolbar
    android:id="@+id/myToolbar"
    ... />

عند استخدام شريط تطبيق يملكه مجزّأ، تنصح Google باستخدام واجهات برمجة التطبيقات Toolbar مباشرةً. عدم استخدام setSupportActionBar() وFragment، التي تُعد مناسبة فقط لأشرطة التطبيقات المملوكة للنشاط.

توسيع القائمة

تحصل طريقة Toolbar المناسبة inflateMenu(int) على معرّف مورد القائمة كمعلمة. لزيادة مورد قائمة XML إلى شريط الأدوات، قم بتمرير resId إلى هذه الطريقة، كما هو موضح في ما يلي مثال:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu);
    }

}

ولتضخيم مورد قائمة XML آخر، يمكنك استدعاء الطريقة مرة أخرى باستخدام resId من القائمة الجديدة. تتم إضافة عناصر القائمة الجديدة إلى القائمة، لا يتم تعديل أو إزالة عناصر القائمة الحالية.

وإذا أردت استبدال مجموعة القوائم الحالية، عليك محو القائمة قبل جارٍ الاتصال بالرقم inflateMenu(int) باستخدام رقم تعريف القائمة الجديد، كما هو موضَّح في ما يلي مثال:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun clearToolbarMenu() {
        viewBinding.myToolbar.menu.clear()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void clearToolbarMenu() {

        viewBinding.myToolbar.getMenu().clear()

    }

}

التعامل مع الأحداث الناتجة عن النقر

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

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.action_settings -> {
                    // Navigate to settings screen.
                    true
                }
                R.id.action_done -> {
                    // Save profile changes.
                    true
                }
                else -> false
            }
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener(item -> {
            switch (item.getItemId()) {
                case R.id.action_settings:
                    // Navigate to settings screen.
                    return true;
                case R.id.action_done:
                    // Save profile changes.
                    return true;
                default:
                    return false;
            }
        });
    }
}

تعديل القائمة ديناميكيًا

عندما يمتلك الجزء شريط التطبيق، يمكنك تعديل Toolbar على بيئة التشغيل تمامًا مثل أي طريقة عرض أخرى.

استكمالاً للمثال السابق، ينبغي أن يكون خيار القائمة حفظ كما يلي غير مرئي حتى يبدأ المستخدم في التعديل، وتختفي مرة أخرى عند النقر عليه:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateToolbar() {
        isEditing = !isEditing

        val saveItem = viewBinding.myToolbar.menu.findItem(R.id.action_done)
        saveItem.isVisible = isEditing

    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateToolbar() {
        isEditing = !isEditing;

        MenuItem saveItem = viewBinding.myToolbar.getMenu().findItem(R.id.action_done);
        saveItem.setVisible(isEditing);
    }

}

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

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        myToolbar.setNavigationIcon(R.drawable.ic_back)

        myToolbar.setNavigationOnClickListener { view ->
            // Navigate somewhere.
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setNavigationIcon(R.drawable.ic_back);
        viewBinding.myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Navigate somewhere.
            }
        });
    }
}