ربط مكونات واجهة المستخدم بـ NavController باستخدام واجهة مستخدم التنقل

يتضمّن مكوّن التنقّل فئة NavigationUI. تحتوي هذه الفئة على طرق ثابتة تدير التنقّل باستخدام شريط التطبيقات العلوي ولوحة التنقل ولوحة التنقل السفلية.

شريط التطبيق العلوي

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

شاشة تعرض شريط تطبيق في أعلى الشاشة
الشكل 1. شاشة تعرض شريط تطبيق في أعلى الشاشة

يحتوي NavigationUI على طُرق لتعديل المحتوى تلقائيًا في NavigationUI عند تنقّل المستخدمين في تطبيقك. على سبيل المثال، يستخدم NavigationUI NavigationUI من الرسم البياني للتنقّل للحفاظ على حداثة عنوان NavigationUI.

<navigation>
    <fragment ...
              android:label="Page title">
      ...
    </fragment>
</navigation>

عند استخدام NavigationUI مع عمليات تنفيذ شريط التطبيقات العلوي الموضّحة أدناه، يمكن تعبئة التصنيف الذي ترفقه بالوجهات تلقائيًا من المَعلمات المقدَّمة للوجهة باستخدام تنسيق {argName} في تصنيفك.

NavigationUI يتيح استخدام أنواع شريط التطبيقات العلوي التالية:

لمزيد من المعلومات عن أشرطة التطبيقات، يُرجى الاطّلاع على إعداد شريط التطبيق.

AppBarConfiguration

يستخدم NavigationUI عنصر AppBarConfiguration لإدارة سلوك زر التنقّل في أعلى يمين منطقة عرض تطبيقك. يتغيّر سلوك زرّ التنقّل استنادًا إلى ما إذا كان المستخدم في وجهة من المستوى الأعلى.

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

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

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph()).build();

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

Kotlin

val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(R.id.main, R.id.profile).build();

إنشاء شريط أدوات

لإنشاء شريط أدوات باستخدام NavigationUI، حدِّد أولاً الشريط في نشاطك الرئيسي، كما هو موضّح:

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar" />
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

بعد ذلك، استخدِم setupWithNavController() من طريقة onCreate() في نشاطك الرئيسي، كما هو موضّح في المثال التالي:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

لضبط زرّ التنقّل بحيث يظهر كزرّ "لأعلى" لجميع الوجهات، نقْل مجموعة فارغة من أرقام تعريف الوِجهات لرحلاتك ذات المستوى الأعلى عند إنشاء AppBarConfiguration. يمكن أن يكون ذلك مفيدًا إذا كان لديك نشاط ثانٍ، على سبيل المثال، يجب أن يعرض زر "الانتقال إلى الأعلى" في Toolbar في جميع الوجهات. ويسمح ذلك للمستخدم بالانتقال مجددًا إلى النشاط الرئيسي عندما لا تتوفّر وجهات أخرى في стек التنقّل مجددًا. يمكنك استخدام setFallbackOnNavigateUpListener() للتحكّم في السلوك الاحتياطي في حال عدم تنفيذ navigateUp()لأي إجراء، كما هو موضّح في المثال التالي:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(
        topLevelDestinationIds = setOf(),
        fallbackOnNavigateUpListener = ::onSupportNavigateUp
    )
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder()
        .setFallbackOnNavigateUpListener(::onSupportNavigateUp)
        .build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

تضمين CollapsingToolbarLayout

لتضمين CollapsingToolbarLayout مع شريط الأدوات، حدِّد أولاً شريط الأدوات والتنسيق المحيط به في نشاطك، كما هو موضّح أدناه:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/tall_toolbar_height">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

بعد ذلك، استخدِم setupWithNavController() من طريقة onCreate في نشاطك الرئيسي، كما هو موضّح أدناه:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)
    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    layout.setupWithNavController(toolbar, navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout);
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration);
}

شريط الإجراءات

لإضافة ميزة التنقّل إلى شريط الإجراءات التلقائي، يمكنك استدعاء setupActionBarWithNavController() من طريقة onCreate() في نشاطك الرئيسي، كما هو موضّح أدناه. يُرجى العلم أنّه عليك الإفصاح عن AppBarConfiguration خارج onCreate()، لأنّك تستخدمه أيضًا عند إلغاء onSupportNavigateUp():

Kotlin

private lateinit var appBarConfiguration: AppBarConfiguration

...

override fun onCreate(savedInstanceState: Bundle?) {
    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

Java

AppBarConfiguration appBarConfiguration;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}

بعد ذلك، يمكنك إلغاء onSupportNavigateUp() للتعامل مع التنقّل للأعلى:

Kotlin

override fun onSupportNavigateUp(): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return navController.navigateUp(appBarConfiguration)
            || super.onSupportNavigateUp()
}

Java

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

إتاحة أشكال شريط التطبيقات

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

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

نوعان من شريط التطبيقات العلوي: شريط أدوات عادي على يمين الشاشة و
            تخطيط شريط التطبيقات الذي يتضمّن شريط أدوات وعلامات تبويب على يمين الشاشة
الشكل 2. نوعان من شريط التطبيق على يمين الصفحة، رمز قياسي Toolbar. على يسار الصفحة، AppBarLayout مع Toolbar وعلامات تبويب

لتنفيذ هذا المثال في أقسام الوجهة باستخدام NavigationUI، حدِّد أولاً شريط التطبيق في كل تنسيق من تنسيقات الأقسام، بدءًا من القسم المقصود الذي يستخدم شريط أدوات عاديًا:

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

بعد ذلك، حدِّد المقتطف المقصود الذي يستخدم شريط تطبيق يتضمّن علامات تبويب:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        ... />

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

        <com.google.android.material.tabs.TabLayout
            ... />

    </com.google.android.material.appbar.AppBarLayout>
    ...
</LinearLayout>

منطق إعدادات التنقّل هو نفسه لكلا المقتطفَين، باستثناء أنّه عليك استدعاء setupWithNavController() من داخل طريقة onViewCreated() لكل مقتطف، بدلاً من بدء هذه المقتطفات من النشاط:

Kotlin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val navController = findNavController()
    val appBarConfiguration = AppBarConfiguration(navController.graph)

    view.findViewById<Toolbar>(R.id.toolbar)
            .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {
    NavController navController = Navigation.findNavController(view);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = view.findViewById(R.id.toolbar);

    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

ربط الوجهات بعناصر القائمة

توفّر NavigationUI أيضًا أدوات مساعدة لربط الوجهات بمكونات واجهة مستخدِم مستندة إلى القائمة. يحتوي NavigationUI على طريقة مساعدة، onNavDestinationSelected()، تستخدِم MenuItem مع NavController الذي يستضيف الوجهة المرتبطة. إذا كان id لـ MenuItem يتطابق مع id للوجهة، يمكن للNavController الانتقال إلى تلك الوجهة.

على سبيل المثال، تحدِّد المقتطفات التالية من XML عنصر قائمة ووجهة باستخدام id وdetails_page_fragment الشائعَين:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    ... >

    ...

    <fragment android:id="@+id/details_page_fragment"
         android:label="@string/details"
         android:name="com.example.android.myapp.DetailsFragment" />
</navigation>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    ...

    <item
        android:id="@+id/details_page_fragment"
        android:icon="@drawable/ic_details"
        android:title="@string/details" />
</menu>

على سبيل المثال، إذا تمت إضافة القائمة من خلال onCreateOptionsMenu() للنشاط، يمكنك ربط عناصر القائمة بالوجهات من خلال إلغاء onOptionsItemSelected() للنشاط للاتّصالonNavDestinationSelected()، كما هو موضّح في المثال التالي:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.onNavDestinationSelected(item, navController)
            || super.onOptionsItemSelected(item);
}

الآن، عندما ينقر المستخدم على عنصر القائمة details_page_fragment، ينتقل التطبيق تلقائيًا إلى الوجهة المقابلة باستخدام id نفسه.

إضافة قائمة تنقّل

"درج التنقّل" هو لوحة واجهة مستخدِم تعرِض قائمة التنقّل الرئيسية في تطبيقك. يظهر الدرج عندما يلمس المستخدم رمز الدرج في شريط التطبيق أو عندما يمرّر إصبعه من الحافة اليسرى للشاشة.

درج مفتوح يعرض قائمة تنقّل
الشكل 3. درج مفتوح يعرض قائمة تنقّل

يظهر رمز الدرج على كل الوجهات ذات المستوى الأعلى التي تستخدم DrawerLayout.

لإضافة درج تنقّل، عليك أولاً تحديد DrawerLayout كملف عرض الجذر. داخل DrawerLayout، أضِف تنسيقًا لمحتوى واجهة المستخدم الرئيسي و عرضًا آخر يحتوي على محتوى درج التنقّل.

على سبيل المثال، يستخدم التنسيق التالي DrawerLayout مع عرضَين فرعيَّين: NavHostFragment لتضمين المحتوى الرئيسي و NavigationView لعرض محتوى درج التنقّل.

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
    <androidx.fragment.app.FragmentContainerView
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <!-- Container for contents of drawer - use NavigationView to make configuration easier -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true" />

</androidx.drawerlayout.widget.DrawerLayout>

بعد ذلك، اربط DrawerLayout برسم التنقّل البياني من خلال تمريره إلى AppBarConfiguration، كما هو موضّح في المثال التالي:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph())
            .setDrawerLayout(drawerLayout)
            .build();

بعد ذلك، في فئة نشاطك الرئيسي، استخدِم setupWithNavController() من طريقة onCreate() في نشاطك الرئيسي، كما هو موضّح أدناه:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<NavigationView>(R.id.nav_view)
        .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    NavigationView navView = findViewById(R.id.nav_view);
    NavigationUI.setupWithNavController(navView, navController);
}

بدءًا من الإصدار Navigation 2.4.0-alpha01، يتم حفظ حالة كل عنصر قائمة واستعادتها عند استخدام setupWithNavController.

شريط التنقّل السفلي

يمكن أن يتعامل NavigationUI أيضًا مع شريط التنقّل السفلي. عندما يختار المستخدم عنصرًا من القائمة، يُطلِق NavController onNavDestinationSelected() NavController onNavDestinationSelected() ويُعدِّل تلقائيًا العنصر المحدّد في شريط التنقل في أسفل الشاشة.

شريط التنقّل السفلي
الشكل 4. شريط تنقّل سفلي:

لإنشاء شريط تنقّل سفلي في تطبيقك، حدِّد الشريط أولاً في نشاطك الرئيسي، كما هو موضّح أدناه:

<LinearLayout>
    ...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

بعد ذلك، في فئة نشاطك الرئيسي، استخدِم setupWithNavController() من طريقة onCreate() في نشاطك الرئيسي، كما هو موضّح أدناه:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    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) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    NavigationUI.setupWithNavController(bottomNav, navController);
}

بدءًا من الإصدار Navigation 2.4.0-alpha01، يتم حفظ حالة كل عنصر قائمة واستعادتها عند استخدام setupWithNavController.

الانتباه إلى أحداث التنقّل

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

يوفّر NavController واجهة OnDestinationChangedListener يتمّ استدعاؤها عند تغيُّر الوجهة الحالية لـ NavController أو تغيُّر مَعلماتها. يمكن تسجيل مستمع جديد باستخدام الإجراء addOnDestinationChangedListener(). يُرجى العِلم أنّه عند الاتصال بالرقم addOnDestinationChangedListener()، إذا كانت الوجهة الحالية متوفّرة، سيتم إرسالها على الفور إلى المستمع.

يستخدم تطبيق NavigationUI OnDestinationChangedListener لجعل مكونات NavigationUI UI الشائعة هذه على دراية بالتنقّل. يُرجى العلم أنّه يمكنك أيضًا استخدام OnDestinationChangedListener بمفرده لجعل أي واجهة مستخدم مخصّصة أو برمجة تطبيقات نشاط تجاري على دراية بأحداث التنقّل.

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

Kotlin

navController.addOnDestinationChangedListener { _, destination, _ ->
   if(destination.id == R.id.full_screen_destination) {
       toolbar.visibility = View.GONE
       bottomNavigationView.visibility = View.GONE
   } else {
       toolbar.visibility = View.VISIBLE
       bottomNavigationView.visibility = View.VISIBLE
   }
}

Java

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
   @Override
   public void onDestinationChanged(@NonNull NavController controller,
           @NonNull NavDestination destination, @Nullable Bundle arguments) {
       if(destination.getId() == R.id.full_screen_destination) {
           toolbar.setVisibility(View.GONE);
           bottomNavigationView.setVisibility(View.GONE);
       } else {
           toolbar.setVisibility(View.VISIBLE);
           bottomNavigationView.setVisibility(View.VISIBLE);
       }
   }
});

المستمعين المستندين إلى الوسيطة

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

<?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"
    android:id="@+id/navigation\_graph"
    app:startDestination="@id/fragmentOne">
    <fragment
        android:id="@+id/fragmentOne"
        android:name="com.example.android.navigation.FragmentOne"
        android:label="FragmentOne">
        <action
            android:id="@+id/action\_fragmentOne\_to\_fragmentTwo"
            app:destination="@id/fragmentTwo" />
    </fragment>
    <fragment
        android:id="@+id/fragmentTwo"
        android:name="com.example.android.navigation.FragmentTwo"
        android:label="FragmentTwo">
        <argument
            android:name="ShowAppBar"
            android:defaultValue="true" />
    </fragment>
</navigation>

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

يمكننا الآن إضافة OnDestinationChangedListener في Activity:

Kotlin

navController.addOnDestinationChangedListener { _, _, arguments ->
    appBar.isVisible = arguments?.getBoolean("ShowAppBar", false) == true
}

Java

navController.addOnDestinationChangedListener(
        new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(
                    @NonNull NavController controller,
                    @NonNull NavDestination destination,
                    @Nullable Bundle arguments
            ) {
                boolean showAppBar = false;
                if (arguments != null) {
                    showAppBar = arguments.getBoolean("ShowAppBar", false);
                }
                if(showAppBar) {
                    appBar.setVisibility(View.VISIBLE);
                } else {
                    appBar.setVisibility(View.GONE);
                }
            }
        }
);

يستدعي NavController دالة ردّ الاتصال هذه كلما تغيّرت وجهة التنقّل. يمكن الآن لـ Activity تعديل حالة مكونات واجهة المستخدم التي يملكها أو مستوى ظهورها استنادًا إلى الوسيطات التي تمّ تلقّيها في دالة الاستدعاء.

من مزايا هذا النهج أنّ Activity لا يرى سوى المَعلمات في الرسم البياني للتنقّل ولا يعرف الأدوار والمسؤوليات الفرديةFragment. وبالمثل، لا تعرف الأجزاء الفردية عن Activity الذي يحتوي عليها ومكونات واجهة المستخدم التي يملكها.

مصادر إضافية

لمزيد من المعلومات عن التنقّل، يمكنك الاطّلاع على المراجع الإضافية التالية.

نماذج

الدروس التطبيقية حول الترميز

مشاركات المدونة

الفيديوهات