Home > Mobile >  using different appbar for specific fragment
using different appbar for specific fragment

Time:11-09

I want to have a static toolbar on the main fragment and specific toolbar with different menu option in other fragments.

This is the main screen:

enter image description here

This is the fragment that I want to have a done button on the toolbar:

enter image description here

but when I press done button, it goes back to the home screen and the done button appears there too:

enter image description here

This is MainActivity code where appbar is created:


    class MainActivity : AppCompatActivity() {
        private lateinit var binding: ActivityMainBinding
        private lateinit var navController: NavController
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
            val navHostFragment =
                supportFragmentManager.findFragmentById(R.id.nav_host_fragment_container) as NavHostFragment
            navController = navHostFragment.findNavController()
    
            val bottomNavigationView = binding.bottomNavigationView
            val navController = findNavController(R.id.nav_host_fragment_container)
            val appBarConfiguration = AppBarConfiguration(setOf(
                R.id.homeFragment,
                R.id.budgetFragment,
                R.id.statsFragment,
                R.id.moreFragment
            ))
    
            setupActionBarWithNavController(navController,appBarConfiguration)
            supportActionBar?.setBackgroundDrawable(ColorDrawable(ContextCompat.getColor(this,R.color.purple)))//change toolbar color
            bottomNavigationView.setupWithNavController(navController)
    
        }
        override fun onSupportNavigateUp(): Boolean {
            return navController.navigateUp() || super.onSupportNavigateUp()
        }
    }

This is the menu for done button:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item android:id="@ id/done"
            android:title="Done"
            app:showAsAction="always"
            android:icon="@drawable/ic_done"/>
    </menu>

This is the menu initialization in fragment:

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            binding = FragmentIncomeBinding.bind(view)
    
            val menuHost: MenuHost = requireActivity()
            menuHost.addMenuProvider(object : MenuProvider {
                override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                    menuInflater.inflate(R.menu.done_button_menu, menu)
                }
    
                override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
                    if(menuItem.itemId == R.id.done){
                        val action = IncomeFragmentDirections.actionIncomeFragmentToHomeFragment()
                        findNavController().navigate(action)
    
                    }
                    return true
                }
            })
        }

In fragment, back button also doesn't work.

What can I do to avoid this situation?

CodePudding user response:

In order to solve this issue, our goal is to create different layout files for each topbar/appbar that we need, and include those layouts within our fragments. Make sure to use FrameLayout as it is the best for performance and will not create a big overhead (nesting complex layouts such as ConstraintLayout will have an impact on performance if done excessively) Check this for including layouts in xml files: https://developer.android.com/develop/ui/views/layout/improving-layouts/reusing-layouts

Firstly, go into your themes.xml and make sure that your application has no default action bar/ appbar like so: parent="Theme.AppCompat.NoActionBar" Basically we won't have 2 topbars active this way.

Then, create your FrameLayout topbars and include them into your complex fragment layouts.

In case you use viewBinding, you can reference a button on the topbar like this: fragmentBinding.topbar.doneButton

  • Related