问题
i have an activity with bottom navigation view with 3 Fragments associated. One of them is a Fragment with a ViewPager2 that uses a FragmentStateAdapter. Inside the createfragment(int position) method of the Adapter I return a couple Instances of another Fragment which has an Options Menu and inside it's onCreate() i call setHasOptionsMenu(true). The Problem is that on initialization of the adapter, the menu from all fragments are visible not just the menu of the currently visible fragment. After the first swipe it seems that the menu gets invalidated and everything is as it should be. The problem also occurs if i notify the adapter about changes that another fragment is added, then another menu item appears for the newly added fragment. I saw a similar question but the answer was to call setHasOptionsMenu() inside the onResume() method of the fragment but that doesn't seem to be the right behavior to handle this. In a comment another user suggested to upgrade ViewPager2 to another version but I am using the latest version. Can anybody tell me how to handle this?
回答1:
I joined StackOverflow just to reply to this question as I've also wasted time on this exact issue.
The fix is to update to the latest alpha01 version of ViewPager2.
implementation "androidx.viewpager2:viewpager2:1.1.0-alpha01"
See: https://developer.android.com/jetpack/androidx/releases/viewpager2#1.1.0-alpha01
Fixed FragmentStateAdapter issue with initial fragment menu visibility when adding a fragment to the FragmentManager. (I9d2ff, b/144442240)
回答2:
I tried updating to the latest viewpager2 alpha as suggested in the currently accepted answer, but it didn't help.
I have seen answers to similar questions where they say to clear the entire menu first. That should work, too, but I have some menu items that are loaded in the Activity, which do not duplicate, and some that load in the fragment, which do duplicate. I want to keep the ones inflated in the Activity and remove only all the ones from all fragments (not just the current fragment, just in case).
My work-around, therefore, is to each time remove only the items added in all fragments, checking to make sure each is actually there (not null) before removing each one. Then, once those have been removed, I inflate the menu(s) needed for all/each fragment.
Note that the existing menu is removed item by item (R.id...) while the inflated one is added by menu (R.menu...) as usual.
In the below sample, the search menu will always be inflated, while the second menu to be inflated will depend on which fragment it currently active.
@Override public void onCreateOptionsMenu (@NonNull Menu menu, @NonNull MenuInflater
inflater)
{
super.onCreateOptionsMenu (menu, inflater);
removeMenuItemIfPresent (menu, R.id.menu_search);
removeMenuItemIfPresent (menu, R.id.menu_sample_filter1);
removeMenuItemIfPresent (menu, R.id.menu_sample_filter2);
inflater.inflate (R.menu.menu_search_menu, menu);
inflater.inflate (mCurrentSection == 0 ? R.menu.menu_frag0 : R.menu.menu_frag1, menu);
}
private void removeMenuItemIfPresent (@NonNull Menu menu, int resourceIDToRemove)
{
MenuItem menuItemToRemove = menu.findItem (resourceIDToRemove);
if (menuItemToRemove != null) {
menu.removeItem (menuItemToRemove.getItemId ());
}
}
来源:https://stackoverflow.com/questions/62153744/android-viewpager2-fragmentstateadapter-shows-menu-from-every-fragment