Search code examples
androidandroid-actionbarfragmenttoolbarback-button

How to sync action bar when back button pressed according fragment and activity


I'm studying menu and toolbar/actionbar. I'm trying the way: one activity container and many fragments. I created and setup a toolbar as actionbar for MainActivity (onCreate):

val myToolbar = this.findViewById<Toolbar>(R.id.myToolbar)
setSupportActionBar(myToolbar)

Then, I add itens by normal way with onCreateOptionMenu and handle click with onOptionsItemSelected

enter image description here

When a call Fragment 1, I change action bar and add back button like this (onCreate):

val actBar = (activity as AppCompatActivity).supportActionBar
    actBar?.setDisplayHomeAsUpEnabled(true)
    actBar?.setDisplayShowHomeEnabled(true)
    actBar?.setDisplayUseLogoEnabled(false)
    actBar?.title = "Fragment 1 toolbar"
    actBar?.subtitle = ""
    setHasOptionsMenu(true)

enter image description here

Then from Fragment 1, the Fragment 2 is called and setup as same way: enter image description here

To handle back button click in fragments, in onOptionsItemSelected:

return if (item.itemId == android.R.id.home) {
     activity?.onBackPressed()
     true
   } else return when (item?.itemId){
     ...
     }
     else -> super.onOptionsItemSelected(item)
   }

And override onBackPressedin MainActivity:

override fun onBackPressed() {
        if(supportFragmentManager.backStackEntryCount > 0){
            supportFragmentManager.popBackStackImmediate()
        }else{
            super.onBackPressed()
        }
    }

The problem is: if I click on back button, it's backing as expected but the last object of action bar is showed. In MainActivity, only action itens are showed as expected: enter image description here

How I can sync the bar according fragment and activity?

Note:

  • I'm using Kotlin, but Java solution are welcome (to convert to kotlin later)

  • The fragments are added to back stack


Solution

  • I found a solution. I leave here for whoever interests: I applied OnBackStackChangedListener that watch changes on back stack. Then, You can make any changes on UI.

        supportFragmentManager.addOnBackStackChangedListener {
             //UI changes
        }
    

    Inside, I check if has some fragment current using the fragment container:

    supportFragmentManager.addOnBackStackChangedListener {
    
                val currentFragment = supportFragmentManager.findFragmentById(R.id.you_fragment_container)
                if (currentFragment == null){
                    //rebuild action bar here or make any another changes
                }
    }
    

    In my case, I compare null that mean container has no fragment. So, if null, the root activity is on screen. This can be used to make changes for any fragment you want to. That's it.