يوفّر شريط التطبيق العلوي مكانًا متسقًا على طول الجزء العلوي من نافذة التطبيق لعرض المعلومات والإجراءات من الشاشة الحالية.
![مثال على شريط التطبيق العلوي](https://developer.android.com/static/images/guide/fragments/top-app-bar.png?authuser=7&hl=ar)
تختلف ملكية شريط التطبيق حسب احتياجات تطبيقك. وعند
استخدام الأجزاء، يمكن تنفيذ شريط التطبيق على شكل 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 القائمة المحدّثة.
![تحتوي قائمة الخيارات الآن على جزء القائمة](https://developer.android.com/static/images/guide/fragments/app-bar-added.png?authuser=7&hl=ar)
التعامل مع أحداث النقر
يمكن أن يستجيب كل نشاط وجزء مشارك في قائمة الخيارات
لللمسات. يتلقى الجزء
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. } }); } }