اجزای UI را با استفاده از NavigationUI به NavController متصل کنید

مولفه Navigation شامل یک کلاس NavigationUI است. این کلاس شامل متدهای ثابتی است که پیمایش را با نوار برنامه بالا، کشوی ناوبری و پیمایش پایین مدیریت می کند.

نوار برنامه بالا

نوار بالای برنامه مکانی ثابت در امتداد بالای برنامه شما برای نمایش اطلاعات و اقدامات از صفحه فعلی فراهم می کند.

صفحه نمایش نوار برنامه بالا
شکل 1. صفحه ای که نوار برنامه بالایی را نشان می دهد.

NavigationUI حاوی روش‌هایی است که به‌طور خودکار محتوا را در نوار برنامه بالای شما به‌روزرسانی می‌کند، زیرا کاربران در برنامه شما پیمایش می‌کنند. برای مثال، NavigationUI از برچسب‌های مقصد در نمودار پیمایش شما استفاده می‌کند تا عنوان نوار بالای برنامه را به‌روز نگه دارد.

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

هنگام استفاده از NavigationUI با اجرای نوار برنامه برتر که در زیر توضیح داده شده است، برچسبی که به مقصدها متصل می کنید می تواند به طور خودکار از آرگومان های ارائه شده به مقصد با استفاده از قالب {argName} در برچسب شما پر شود.

NavigationUI از انواع بالای نوار برنامه زیر پشتیبانی می کند:

برای اطلاعات بیشتر در مورد نوار برنامه، به تنظیم نوار برنامه مراجعه کنید.

AppBarConfiguration

NavigationUI از یک شی AppBarConfiguration برای مدیریت رفتار دکمه ناوبری در گوشه سمت چپ بالای ناحیه نمایش برنامه شما استفاده می کند. رفتار دکمه پیمایش بسته به اینکه کاربر در یک مقصد سطح بالا باشد تغییر می کند.

مقصد سطح بالا، مقصد اصلی یا بالاترین سطح در مجموعه ای از مقاصد مرتبط با سلسله مراتب است. مقصدهای سطح بالا دکمه Up را در نوار بالای برنامه نمایش نمی دهند زیرا مقصد سطح بالاتری وجود ندارد. به طور پیش فرض، مقصد شروع برنامه شما تنها مقصد سطح بالا است.

هنگامی که کاربر در یک مقصد سطح بالا قرار دارد، دکمه ناوبری به نماد کشو تبدیل می شود اگر مقصد از DrawerLayout استفاده کند. اگر مقصد از DrawerLayout استفاده نمی کند، دکمه پیمایش پنهان می شود. هنگامی که کاربر در هر مقصد دیگری است، دکمه ناوبری به عنوان یک دکمه بالا ظاهر می شود . برای پیکربندی دکمه ناوبری تنها با استفاده از مقصد شروع به عنوان مقصد سطح بالا، یک شی AppBarConfiguration ایجاد کنید و نمودار ناوبری مربوطه را مطابق شکل زیر ارسال کنید:

کاتلین

val appBarConfiguration = AppBarConfiguration(navController.graph)

جاوا

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

در برخی موارد، ممکن است لازم باشد به جای استفاده از مقصد شروع پیش‌فرض، چندین مقصد سطح بالا را تعریف کنید. استفاده از BottomNavigationView یک مورد استفاده رایج برای این کار است، که در آن ممکن است صفحات خواهر و برادری داشته باشید که به صورت سلسله مراتبی به یکدیگر مرتبط نیستند و ممکن است هر کدام مجموعه ای از مقاصد مرتبط خود را داشته باشند. برای مواردی مانند این، می‌توانید در عوض مجموعه‌ای از شناسه‌های مقصد را به سازنده ارسال کنید، همانطور که در زیر نشان داده شده است:

کاتلین

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

جاوا

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() در اکتیویتی اصلی خود فراخوانی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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)
}

جاوا

@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() هیچ کاری انجام نمی دهد استفاده کنید:

کاتلین

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)
}

جاوا

@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 اکتیویتی اصلی خود فراخوانی کنید، همانطور که در زیر نشان داده شده است:

کاتلین

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)
}

جاوا

@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() نیز از آن استفاده می کنید:

کاتلین

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)
}

جاوا

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() را لغو کنید تا ناوبری Up را مدیریت کنید:

کاتلین

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

جاوا

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

از تغییرات نوار برنامه پشتیبانی کنید

زمانی که طرح نوار برنامه برای هر مقصد در برنامه شما مشابه باشد، افزودن نوار برنامه بالا به فعالیت شما به خوبی کار می کند. با این حال، اگر نوار برنامه بالای شما به طور قابل توجهی در بین مقصدها تغییر می کند، به جای آن، نوار برنامه برتر را از فعالیت خود حذف کرده و در هر قسمت مقصد تعریف کنید.

به عنوان مثال، یکی از مقصدهای شما ممکن است از Toolbar استاندارد استفاده کند، در حالی که مقصد دیگری از یک AppBarLayout برای ایجاد یک نوار برنامه پیچیده تر با برگه ها، همانطور که در شکل 2 نشان داده شده است، استفاده می کند.

دو تنوع بالای نوار برنامه؛ یک نوار ابزار استاندارد در سمت چپ، و یک appbarlayout با نوار ابزار و برگه ها در سمت راست
شکل 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() هر فرگمنت فراخوانی کنید، به جای اینکه آنها را از اکتیویتی مقدار دهی اولیه کنید:

کاتلین

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

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

جاوا

@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() Activity اضافه شده است، می‌توانید موارد منو را با نادیده گرفتن onOptionsItemSelected() Activity برای فراخوانی onNavDestinationSelected() با مقصد مرتبط کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

@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 به نمودار ناوبری خود متصل کنید:

کاتلین

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

جاوا

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

در مرحله بعد، در کلاس اکتیویتی اصلی خود، مطابق شکل زیر، setupWithNavController() را از متد onCreate() اکتیویتی اصلی خود فراخوانی کنید:

کاتلین

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)
}

جاوا

@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() را فراخوانی می کند و به طور خودکار مورد انتخاب شده را در نوار ناوبری پایین به روز می کند.

نوار ناوبری پایین
شکل 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() اکتیویتی اصلی خود فراخوانی کنید:

کاتلین

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)
}

جاوا

@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 ذخیره و بازیابی می شود.

برای یک مثال جامع که شامل ناوبری پایین است، به نمونه پیمایش پیشرفته اجزای معماری اندروید در GitHub مراجعه کنید.

به رویدادهای ناوبری گوش دهید

تعامل با NavController روش اصلی برای پیمایش بین مقصد است. NavController مسئول جایگزینی محتویات NavHost با مقصد جدید است. در بسیاری از موارد، عناصر UI - مانند نوار بالای برنامه یا سایر کنترل‌های پیمایش دائمی مانند BottomNavigationBar - خارج از NavHost زندگی می‌کنند و باید در حین حرکت بین مقصدها به‌روزرسانی شوند.

NavController یک رابط OnDestinationChangedListener ارائه می دهد که زمانی فراخوانی می شود که مقصد فعلی NavController یا آرگومان های آن تغییر کند. یک شنونده جدید می تواند از طریق متد addOnDestinationChangedListener() ثبت شود. توجه داشته باشید که هنگام فراخوانی addOnDestinationChangedListener() ، اگر مقصد فعلی وجود داشته باشد، بلافاصله برای شنونده شما ارسال می شود.

NavigationUI از OnDestinationChangedListener استفاده می‌کند تا این مؤلفه‌های معمولی رابط کاربری را به ناوبری آگاه کند. البته توجه داشته باشید که می‌توانید از OnDestinationChangedListener به تنهایی استفاده کنید تا هر رابط کاربری سفارشی یا منطق تجاری را از رویدادهای ناوبری آگاه کنید.

به عنوان مثال، ممکن است عناصر رابط کاربری مشترکی داشته باشید که می‌خواهید در برخی از قسمت‌های برنامه خود نشان دهید و در قسمت‌های دیگر پنهان کنید. با استفاده از OnDestinationChangedListener خود، می‌توانید به طور انتخابی این عناصر رابط کاربری را بر اساس مقصد مورد نظر نشان داده یا پنهان کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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
   }
}

جاوا

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 اضافه کنیم:

کاتلین

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

جاوا

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 می تواند وضعیت یا نمایان بودن مؤلفه های UI متعلق به خود را بر اساس آرگومان های دریافت شده در تماس برگشتی به روز کند.

یکی از مزایای این رویکرد این است که Activity فقط آرگومان‌ها را در نمودار ناوبری می‌بیند و نقش‌ها و مسئولیت‌های تک تک Fragment را نمی‌داند. به طور مشابه، تک تک قطعات از Activity و مؤلفه‌های UI متعلق به خود اطلاعی ندارند.

منابع اضافی

برای کسب اطلاعات بیشتر در مورد ناوبری، به منابع اضافی زیر مراجعه کنید.

نمونه ها

Codelabs

پست های وبلاگ

ویدیوها