חיבור רכיבים של ממשק המשתמש ל-NavController באמצעות NavigationUI

רכיב הניווט כולל NavigationUI בכיתה. הכיתה הזו מכילה שיטות סטטיות שמנהלות את הניווט באמצעות החלק העליון של המסך את סרגל האפליקציות, את חלונית ההזזה לניווט ואת הניווט התחתון.

סרגל האפליקציה העליון

סרגל האפליקציות העליון מספק מקום עקבי בחלק העליון של האפליקציה להצגת מידע והפעולות במסך הנוכחי.

מסך שבו מוצג סרגל אפליקציות עליון
איור 1. מסך שבו מוצג סרגל עליון של האפליקציה.

NavigationUI כולל שיטות שמעדכנות באופן אוטומטי תוכן שמוצג בראש הדף בסרגל האפליקציות בזמן שהמשתמשים מנווטים באפליקציה. לדוגמה, NavigationUI משתמש בתחילית תוויות היעד מתרשים הניווט כדי לשמור את הכותרת של האפליקציה העליונה העמודה מתעדכנת.

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

כשמשתמשים ב-NavigationUI עם יישומי סרגל האפליקציות המובילים שמפורטים בהמשך, אפשר לאכלס את התווית שמצרפים ליעדים באופן אוטומטי ארגומנטים שסופקו ליעד באמצעות הפורמט של {argName} התיוג.

NavigationUI תומך בסוגים המובילים הבאים של סרגלי האפליקציות:

מידע נוסף על סרגלי אפליקציות זמין במאמר הגדרת סרגל האפליקציות.

הגדרת AppBarConfiguration

NavigationUI משתמש ב-AppBarConfiguration אובייקט לניהול ההתנהגות של לחצן הניווט בפינה הימנית העליונה. של אזור התצוגה של האפליקציה. ההתנהגות של לחצן הניווט משתנה בהתאם מציין אם המשתמש נמצא ביעד ברמה העליונה.

יעד ברמה עליונה הוא יעד ברמה הבסיסית (root), או יעד ברמה הגבוהה ביותר, בקבוצה של יעדים הקשורים בהיררכיה. ביעדים ברמה העליונה לא מוצג לחצן 'למעלה' בסרגל העליון של האפליקציה כי אין יעד ברמה גבוהה יותר. על ידי ברירת המחדל, יעד ההתחלה של האפליקציה הוא היעד היחיד ברמה העליונה.

כשהמשתמש נמצא ביעד ברמה העליונה, לחצן הניווט הופך סמל של חלונית הזזה אם היעד הוא DrawerLayout. אם היעד לא כולל DrawerLayout, לחצן הניווט מוסתר. כשהמשתמש נמצא ביעד אחר, לחצן הניווט מופיע כלחצן למעלה כדי להגדיר את לחצן הניווט באמצעות יעד ההתחלה בלבד היעד ברמה העליונה, יוצרים אובייקט AppBarConfiguration ומעבירים בתרשים הניווט המתאים, כמו בדוגמה הבאה:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph)

Java

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

במקרים מסוימים, יכול להיות שתצטרכו להגדיר במקום זאת כמה יעדים ברמה העליונה של שימוש ביעד ההתחלה המוגדר כברירת מחדל. השימוש ב-BottomNavigationView הוא במקרה כזה, יכול להיות שיש לכם מסכים אחים שלא קשורות זו לזו מבחינה היררכית, ולכל אחת מהן יכולה להיות קבוצה משלה יעדים. במקרים כאלה, אפשר במקום זאת להעביר קבוצת יעדים מזהים ל-constructor, כפי שמוצג בהמשך:

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() מה-method 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 בסרגל הכלים, תחילה צריך להגדיר סרגל הכלים והפריסה שמסביב בפעילות שלך, כפי שמוצג בהמשך:

<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 ברמה הבסיסית (root) צפייה. בתוך 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);
}

מתחיל בעוד ניווט 2.4.0-alpha01, כשהמצב של כל אפשרות בתפריט נשמר ומשוחזר, כשאתם משתמשים setupWithNavController.

ניווט בחלק התחתון

NavigationUI יכול גם לטפל בניווט התחתון. כשמשתמש בוחר תפריט פריט, הקריאות של 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);
}

מתחיל בעוד ניווט 2.4.0-alpha01, כשהמצב של כל אפשרות בתפריט נשמר ומשוחזר, כשאתם משתמשים setupWithNavController.

לדוגמה מקיפה שכוללת ניווט בחלק התחתון, ראו את דגימת ניווט מתקדמת לרכיבי הארכיטקטורה של Android ב-GitHub.

האזנה לאירועי ניווט

אינטראקציה עם NavController היא השיטה העיקרית לניווט בין יעדים. NavController אחראי להחלפת התוכן של NavHost עם היעד החדש. במקרים רבים, רכיבי ממשק המשתמש — כמו סרגל אפליקציה עליון פקדי ניווט קבועים אחרים, כמו BottomNavigationBar – בשידור חי בחוץ של NavHost וצריך לעדכן אותם במהלך הניווט בין יעדים.

NavController מציע ממשק OnDestinationChangedListener בוצעה קריאה כשהיעד הנוכחי של NavController או שהארגומנטים שלה משתנים. ניתן להירשם למאזינים חדשים דרך addOnDestinationChangedListener() . הערה: כשמבצעים קריאה אל addOnDestinationChangedListener(), אם קיים יעד נוכחי, והוא נשלח מיד למאזינים.

NavigationUI משתמש ב-OnDestinationChangedListener כדי להפוך את ממשקי המשתמש הנפוצים האלה מודעים לניווט. עם זאת, שימו לב שאפשר להשתמש גם 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 המכיל ועל רכיבי ממשק המשתמש שבבעלותו.

מקורות מידע נוספים

מידע נוסף על הניווט זמין במקורות המידע הנוספים הבאים.

דוגמיות

שיעורי Lab

פוסטים בבלוגים

סרטונים