3

Below is the code

I have defined all my top level destinations with AppbarConfiguraion.

class MainActivity : DaggerAppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    lateinit var navController: NavController
    lateinit var binding: MainActivityBinding
    lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        navController = findNavController(R.id.navigation)
        setSupportActionBar(binding.toolbar)
        supportActionBar!!.setDisplayShowHomeEnabled(true)

        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.homeFragment,
                R.id.bulletinsFragment,
                R.id.serviceFragment,
                R.id.paymentsFragment,
                R.id.feedBackFragment,
                R.id.formsFragment,
                R.id.surveysFragment
            ),
            drawer_layout)
        setupActionBarWithNavController(
            this, navController, appBarConfiguration
            )

        val toggle = ActionBarDrawerToggle(
            this,
            drawer_layout,
            binding.toolbar,
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close
        )
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()
        sideNV.setNavigationItemSelectedListener(this)
    }

    override fun onBackPressed() {
        if ((drawer_layout as DrawerLayout).isDrawerOpen(GravityCompat.START)) {
            (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
        } else {
            findNavController(R.id.navigation).navigateUp()
        }
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {
            R.id.nav_home, R.id.nav_service, R.id.nav_payments, R.id.nav_forms, R.id.nav_bulletins,
            R.id.nav_surveys, R.id.nav_feedbacks -> {
                navController.navigate(item.itemId)
            }
        }
        (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
        return true
    }

    override fun onSupportNavigateUp() = findNavController(R.id.navigation).navigateUp()
}

When moving from the top level fragments to other fragments the back arrow is shown but when on clicking it opens the drawer itself. When on clicking the system back button it's working fine.

Manifest

<activity
        android:name=".home.MainActivity"
        android:label="@string/app_name"
        android:parentActivityName=".home.MainActivity"
        android:theme="@style/AppTheme.NoActionBar">
</activity>
Abraham Mathew
  • 2,029
  • 3
  • 21
  • 42

3 Answers3

4
class MainActivity : DaggerAppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    lateinit var navController: NavController
    lateinit var binding: MainActivityBinding
    lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        navController = findNavController(R.id.navigation)
        setSupportActionBar(binding.toolbar)
        supportActionBar!!.setDisplayShowHomeEnabled(true)

        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.homeFragment,
                R.id.bulletinsFragment,
                R.id.serviceFragment,
                R.id.paymentsFragment,
                R.id.feedBackFragment,
                R.id.formsFragment,
                R.id.surveysFragment
            ),
            drawer_layout
        )
        setupActionBarWithNavController(
            this, navController, appBarConfiguration
        )

        val toggle = ActionBarDrawerToggle(
            this,
            drawer_layout,
            binding.toolbar,
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close
        )
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()
        sideNV.setNavigationItemSelectedListener(this)
        toolbar?.setNavigationOnClickListener {
            findNavController(R.id.navigation).navigateUp(appBarConfiguration)
        }
    }

    override fun onBackPressed() {
        if ((drawer_layout as DrawerLayout).isDrawerOpen(GravityCompat.START)) {
            (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
        } else {
            super.onBackPressed()
        }
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {
            R.id.nav_home, R.id.nav_service, R.id.nav_payments, R.id.nav_forms, R.id.nav_bulletins,
            R.id.nav_surveys, R.id.nav_feedbacks -> {
                navController.navigate(item.itemId)
            }
        }
        (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
        return true
    }

    override fun onSupportNavigateUp() = findNavController(R.id.navigation).navigateUp()
}

i just changed my code and added toolbar NavigationOnClickListener and in that listener i just added navigateUp(appBarConfiguration).Also there is a slight change in the onBackPressed() as in my previous code it will not close the app even if we are at the last fragment in the stack

Abraham Mathew
  • 2,029
  • 3
  • 21
  • 42
  • Thanks, `toolbar.setNavigationOnClickListener{navController.navigateUp(appBarConfiguration)}` did work for me. – Shvet Jul 23 '21 at 05:38
3

Try this

  override fun onSupportNavigateUp(): Boolean {
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
Kashifa
  • 406
  • 4
  • 7
1

First, remove the following because the navigation will handle this for you

val toggle = ActionBarDrawerToggle(
        this,
        drawer_layout,
        binding.toolbar,
        R.string.navigation_drawer_open,
        R.string.navigation_drawer_close
    )
    drawer_layout.addDrawerListener(toggle)
    toggle.syncState()
    sideNV.setNavigationItemSelectedListener(this)
}

override fun onBackPressed() {
    if ((drawer_layout as DrawerLayout).isDrawerOpen(GravityCompat.START)) {
        (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
    } else {
        findNavController(R.id.navigation).navigateUp()
    }
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {

    when (item.itemId) {
        R.id.nav_home, R.id.nav_service, R.id.nav_payments, R.id.nav_forms, R.id.nav_bulletins,
        R.id.nav_surveys, R.id.nav_feedbacks -> {
            navController.navigate(item.itemId)
        }
    }
    (drawer_layout as DrawerLayout).closeDrawer(GravityCompat.START)
    return true
}
Mustafa ALMulla
  • 870
  • 2
  • 10
  • 23
  • No,It won't work.How will i get control over the toggle button, how will we detect the click on each item? – Abraham Mathew May 21 '19 at 05:04
  • This part of the navigation architecture component. Which should take care of the navigation. If you need to do something when the view/ fragment change you need to use on distinction change call back – Mustafa ALMulla May 21 '19 at 18:50
  • 1
    I didn't get you can you please explain, coz i know it won't work and I tried removing the code .The result was obvious ,toggle was not working, not detecting click in navigation menu. – Abraham Mathew May 22 '19 at 04:56
  • 1
    Please read https://developer.android.com/guide/navigation/navigation-ui it has all the information about how this work – Mustafa ALMulla May 22 '19 at 19:58