Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple options menu showing up on app bar

Let me add more context:

I run bottom view navigation with a ViewPager2. For all 4 of my tab/fragments of my bottom navigation view I have an options menu which I created separately dynamically in each fragment.

Now, when we navigate through the app, it behaves correctly as every options menu is displayed ONLY for their respective fragment.

Problem is: Only when the app is launched, all the options menus from all the the 4 fragments show up on the start destination fragment's tab. BUT, once we swipe and swipe back, only the start destinations options menu is shown on the app bar. As is for every of the other 3 fragment/tabs.

Theory: I think it has something to do with onCreateOptionsMenu which is called when all four fragments are also created to which they share an app bar.

Is anybody familiar with this type of issue? Here is my PagerAdapters code for my ViewPager:

const val F1_PAGE_INDEX = 0
const val F2_PAGE_INDEX = 1
const val F3_PAGE_INDEX = 2
const val F4_PAGE_INDEX = 3

class PagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    /**
     * Mapping of the ViewPager page indexes to their respective Fragments
     */
    private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
        F1_PAGE_INDEX to { FirstFragment() },
        F2_PAGE_INDEX to { SecondFragment() },
        F3_PAGE_INDEX to { ThirdFragment() },
        F4_PAGE_INDEX to { FourthFragment() }
    )

    override fun getItemCount() = tabFragmentsCreators.size

    override fun createFragment(position: Int): Fragment {
        return tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
    }

}

Here is also my Home View Pager Fragment where I create my bottom Navigation and affect to to the main fragments:

class HomeViewPagerFragment(): Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val binding = FragmentViewPagerBinding.inflate(inflater, container, false)

        val viewPager = binding.viewPager

        viewPager.isUserInputEnabled = false

        viewPager.adapter = PagerAdapter(this)

        //Save states of four fragments
        viewPager.offscreenPageLimit = 4

        (activity as AppCompatActivity).setSupportActionBar(binding.toolbar)

        val bottomNavigation = binding.bottomNavView

        bottomNavigation.setOnNavigationItemSelectedListener(
            BottomNavigationView.OnNavigationItemSelectedListener { item ->
                when (item.itemId) {
                    R.id.fragment1_destination -> viewPager.currentItem = F1_PAGE_INDEX
                    R.id.fragment2_destination -> viewPager.currentItem = F2_PAGE_INDEX
                    R.id.fragment3_destination -> viewPager.currentItem = F3_PAGE_INDEX
                    R.id.fragment4_destination -> viewPager.currentItem = F4_PAGE_INDEX
                }
                true
            })
        return binding.root
    }


}

The starting destination (first fragment) is where all the fragment's menu are shown at app start.

Any kind of help is appreciated! Thank you!

like image 870
matija Avatar asked Oct 22 '25 23:10

matija


1 Answers

Issue: After endless hours, we have found a solution. The issue was directly created when we set the off screen page limit to 4. That causes all the fragments to be created at the same time, thus, obligates the option menus to be shown at launch on the starting destinations fragment since we instructed setHasOptionsMenu(true) in the onCreate of each fragment.

Solution: Simply, set the options menu to true in the onResumeof the fragment to only be called when we swipe to the respective fragment in this manner:

override fun onResume() {
    super.onResume()
    setHasOptionsMenu(true)
}
like image 136
matija Avatar answered Oct 24 '25 15:10

matija



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!