يمكن أن يتكون الرسم البياني للتنقل من أي مجموعة مما يلي:
- وجهة فردية، مثل وجهة
<fragment>
. - رسم بياني متداخل يضم مجموعة من الوجهات ذات الصلة
- عنصر
<include>
، الذي يسمح لك بتضمين ملف رسم بياني آخر للتنقّل كما لو كان مضمَّنًا.
تسمح لك هذه المرونة بدمج الرسوم البيانية الأصغر حجمًا معًا لتشكيل رسم بياني كامل للتنقّل في تطبيقك، حتى إذا كانت رسومات التنقّل الأصغر توفّر عن طريق وحدات منفصلة.
بالنسبة إلى الأمثلة في هذا الموضوع، تركّز كل
وحدة ميزات
على ميزة واحدة
وتوفّر رسمًا بيانيًا واحدًا للتنقل يضم جميع الوجهات
اللازمة لتنفيذ هذه الميزة. في تطبيق إنتاج، قد يكون لديك العديد من الوحدات
الفرعية في مستوى أقل التي تمثل تفاصيل تنفيذ وحدة الميزات ذات المستوى الأعلى هذه. يتم تضمين كل وحدة من وحدات الميزات هذه، سواء بشكل مباشر أو غير مباشر، في وحدة app
الخاصة بك. ويتسم مثال التطبيق متعدد الوحدات المستخدَم في هذا المستند بالبنية التالية:
![رسم بياني للتبعية لنموذج تطبيق متعدّد الوحدات](https://developer.android.com/static/images/guide/navigation/multimodule-structure.png?authuser=7&hl=ar)
![وجهة بداية نموذج التطبيق](https://developer.android.com/static/images/guide/navigation/multimodule-screen.png?authuser=7&hl=ar)
وكل وحدة ميزة هي وحدة مستقلة لها رسم بياني للتنقل والوجهات. تعتمد وحدة app
على كل منها، وتتم إضافتها كتفاصيل تنفيذ في ملف build.gradle
الخاص بها، كما هو موضّح:
رائع
dependencies { ... implementation project(":feature:home") implementation project(":feature:favorites") implementation project(":feature:settings")
Kotlin
dependencies { ... implementation(project(":feature:home")) implementation(project(":feature:favorites")) implementation(project(":feature:settings"))
دور وحدة app
وحدة app
مسؤولة عن توفير الرسم البياني الكامل لتطبيقك
وإضافة NavHost
إلى واجهة المستخدم لديك. ضمن الرسم البياني للتنقّل في وحدة app
، يمكنك الرجوع إلى الرسومات البيانية للمكتبة باستخدام <include>
. إنّ استخدام <include>
يشبه عمليًا استخدام رسم بياني مدمج، إلا أنّ <include>
يدعم الرسوم البيانية من وحدات مشاريع أخرى أو من مشاريع المكتبة، كما هو موضّح في المثال التالي:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
</navigation>
بعد تضمين مكتبة في الرسم البياني للتنقُّل ذي المستوى الأعلى، يمكنك الانتقال إلى الرسومات البيانية للمكتبة حسب الحاجة. على سبيل المثال، يمكنك إنشاء إجراء للانتقال إلى الرسم البياني للإعدادات من جزء في الرسم البياني للتنقل، كما هو موضح:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
<fragment
android:id="@+id/random_fragment"
android:name="com.example.android.RandomFragment"
android:label="@string/fragment_random" >
<!-- Launch into Settings Navigation Graph -->
<action
android:id="@+id/action_random_fragment_to_settings_nav_graph"
app:destination="@id/settings_nav_graph" />
</fragment>
</navigation>
عندما تحتاج وحدات متعددة لميزات إلى الإشارة إلى مجموعة مشتركة من الوجهات،
مثل الرسم البياني لتسجيل الدخول، يجب عدم تضمين هذه الوجهات الشائعة في الرسم البياني للتنقل في كل وحدة من وحدات الميزات. بدلاً من ذلك، أضِف هذه الوجهات الشائعة إلى الرسم البياني للتنقّل في وحدة "app
".
يمكن لكل وحدة من الوحدات التنقل عبر وحدات الميزات
للانتقال إلى تلك الوجهات المشتركة.
في المثال السابق، يحدد الإجراء وجهة تنقّل @id/settings_nav_graph
. يشير رقم التعريف هذا إلى وجهة
يتم تحديدها ضمن الرسم البياني المضمّن @navigation/settings_navigation.
التنقّل على المستوى الأعلى في وحدة التطبيق
يتضمّن مكوِّن التنقّل فئة NavigationUI
.
تحتوي هذه الفئة على طرق ثابتة تدير التنقل من خلال شريط
التطبيق العلوي ودرج التنقل والتنقل السفلي. إذا كانت وجهات تطبيقك ذات المستوى الأعلى تتألف من عناصر واجهة المستخدم التي توفّرها وحدات الميزات، تكون وحدة app
مكانًا طبيعيًا لإدراج عناصر التنقّل وواجهة المستخدم ذات المستوى الأعلى. بما أنّ وحدة التطبيق تعتمد على وحدات الميزات التعاونية، يمكنك الوصول إلى جميع وجهاتها من خلال الرمز الذي تم تحديده ضمن وحدة التطبيق. هذا يعني أنّه يمكنك استخدام
NavigationUI
لربط الوجهات بأصناف القائمة
إذا كان رقم تعريف السلعة يتطابق مع رقم تعريف الوجهة.
في الشكل 2، يحدد المثال 2 لوحدة app
BottomNavigationView
في نشاطها الرئيسي. تتطابق معرفات عناصر القائمة في القائمة مع معرفات
الرسم البياني للتنقل في الرسوم البيانية للمكتبة:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/home_nav_graph"
android:icon="@drawable/ic_home"
android:title="Home"
app:showAsAction="ifRoom"/>
<item
android:id="@id/favorites_nav_graph"
android:icon="@drawable/ic_favorite"
android:title="Favorites"
app:showAsAction="ifRoom"/>
<item
android:id="@id/settings_nav_graph"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="ifRoom" />
</menu>
للسماح لـ "NavigationUI
" بالتعامل مع
شريط التنقّل السفلي، عليك الاتصال
setupWithNavController()
من onCreate()
في فئة النشاط الرئيسية، على النحو الموضّح في
المثال التالي:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<BottomNavigationView>(R.id.bottom_nav) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); BottomNavigationView bottomNav = findViewById(R.id.bottom_nav); NavigationUI.setupWithNavController(bottomNav, navController); }
بعد تفعيل هذا الرمز، ينتقل NavigationUI
إلى الرسم البياني المناسب للمكتبة عندما ينقر المستخدم على أحد عناصر التنقّل السفلية.
ضَع في اعتبارك أنّه من الممارسات السيئة بشكل عام أن تعتمد وحدة تطبيقك على وجهة معيّنة مضمّنة بشكل كبير في الرسم البياني للتنقل في وحدات الميزات. وفي معظم الحالات، تريد أن تتعرّف وحدة التطبيق على نقطة الدخول فقط إلى أي رسوم بيانية مضمَّنة أو مضمّنة للتنقل (ينطبق ذلك خارج وحدات الميزات أيضًا). إذا كنت بحاجة إلى إنشاء رابط إلى وجهة معيّنة ضمن الرسم البياني للتنقل في مكتبتك، ننصحك باستخدام رابط لصفحة في التطبيق. يعد الربط بصفحة في التطبيق الطريقة الوحيدة لانتقال المكتبة إلى وجهة في الرسم البياني للتنقل في مكتبة أخرى.
التنقّل بين وحدات الميزات
وفي وقت التجميع، لا يمكن لوحدات الميزات المستقلة التعرّف على بعضها، لذا لا يمكنك استخدام أرقام التعريف للانتقال إلى وجهات في وحدات أخرى. بدلاً من ذلك، استخدِم رابطًا لصفحة في التطبيق للانتقال مباشرةً إلى وجهة مرتبطة برابط ضمني لصفحة في التطبيق.
متابعةً للمثال السابق، تخيَّل أنّك بحاجة إلى الانتقال من زر في وحدة :feature:home
إلى وجهة مضمَّنة في الوحدة :feature:settings
. يمكنك إجراء ذلك عن طريق إضافة رابط لموضع معيّن إلى الوجهة في الرسم البياني للتنقل
في الإعدادات، كما هو موضّح:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/settings_nav_graph"
app:startDestination="@id/settings_fragment_one">
...
<fragment
android:id="@+id/settings_fragment_two"
android:name="com.example.google.login.SettingsFragmentTwo"
android:label="@string/settings_fragment_two" >
<deepLink
app:uri="android-app://example.google.app/settings_fragment_two" />
</fragment>
</navigation>
بعد ذلك، أضِف الرمز التالي إلى onClickListener
للزر في جزء الصفحة الرئيسية:
Kotlin
button.setOnClickListener { val request = NavDeepLinkRequest.Builder .fromUri("android-app://example.google.app/settings_fragment_two".toUri()) .build() findNavController().navigate(request) }
Java
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { NavDeepLinkRequest request = NavDeepLinkRequest.Builder .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two")) .build(); NavHostFragment.findNavController(this).navigate(request); } });
على عكس التنقل باستخدام أرقام تعريف الإجراءات أو الوجهة، يمكنك الانتقال إلى أي معرّف موارد منتظم (URI) في أي رسم بياني، حتى على مستوى الوحدات.
عند التنقّل باستخدام معرّف موارد منتظم (URI)، لا تتم إعادة ضبط حزمة الرجوع. يختلف هذا السلوك عن التنقل الصريح عبر رابط لصفحة في التطبيق، حيث يتم استبدال الحزمة الخلفية عند التنقل.