Fillipe Duoli
Fillipe Duoli

Reputation: 1370

How to properly add options menu on a single fragment with navigation component without broke "up behavior"

I'm having some trouble to add options menu on a single fragment because it's breaking the navigation Up. Here my code

I have an single Activity with NoActionBar style and with this layout

<layout 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:fitsSystemWindows="true"
    tools:context=".ui.MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white">

        <fragment
            android:id="@+id/mainNavigationFragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/main_graph" />

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbarLayout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="top">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize" />

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

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            app:labelVisibilityMode="labeled"
            app:menu="@menu/main_bottom_nav" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</layout>

in activity onCreate I make this setup for navigation

private fun setupNavigation() {
        val navController = findNavController(R.id.mainNavigationFragment)

        //each fragment of botton nav
        val appBarConfiguration = AppBarConfiguration(setOf(
                R.id.actionSchedule,
                R.id.actionPayment,
                R.id.actionNotification,
                R.id.actionAccount))

        toolbar.setupWithNavController(navController, appBarConfiguration)
        bottomNavigationView.setupWithNavController(navController)
    }

override fun onSupportNavigateUp() =
            findNavController(R.id.mainNavigationFragment).navigateUp()

on each botton nav fragment I have some destinations and everything work as expected.

Now I need to add an menu only on right most fragment of botton nav, then on this specific fragment I add setHasOptionsMenu(true) in onCreate and inflate menu in onCreateOptionsMenu, but the menu does not appear.

Then I add setSupportActionBar(toolbar) on activity onCreate.

Now the menu appear only on this fragment but it's broke all 'UP' (back arrow on toolbar) of any destination (the back arrow appears, but when i press nothing happens). If I remove setSupportActionBar(toolbar) of activity the UP work again but not the toolbar menu.

What I need to do to make the menu work only in one fragment without broke anything else? Thanks

Upvotes: 8

Views: 7091

Answers (2)

Hadi Ahmadi
Hadi Ahmadi

Reputation: 1982

if using toolbar do this: in Acitvity:

class MyActivity : AppCompatActivity() {
private var currentNavController: NavController? = null

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

    currentNavController = findNavController(R.id.settingNavHost)

    currentNavController?.let {
        val appBarConfiguration = AppBarConfiguration
            .Builder()
            .setFallbackOnNavigateUpListener {
                onBackPressed()
                true
            }.build()

        setSupportActionBar(toolbar)
        toolbar.setupWithNavController(it, appBarConfiguration)
    }
}

}

and in fragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    setHasOptionsMenu(true)
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    super.onCreateOptionsMenu(menu, inflater)
    inflater.inflate(R.menu.my_menu, menu)

}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    if (item.itemId == R.id.action_save) {
        saveInfo()
    }

    return super.onOptionsItemSelected(item)
}

Upvotes: 7

ianhanniballake
ianhanniballake

Reputation: 199805

If you're using setSupportActionBar, you must use setupActionBarWithNavController(), not toolbar.setupWithNavController as per the documentation.

Upvotes: 7

Related Questions