Search code examples
androidandroid-menuandroid-viewpager2android-optionsmenuoncreateoptionsmenu

Options menu inflate wrongly in viewpager2


I have 4 fragments but for each fragments it has different different menu options in my app with viewpager2 so the user swipe through these all fragments and when the app starts the menu option for the first fragment showing the wrong which is 4th fragment menu option item that wrongly inflated in 1st fragment whenever I open the app it only occur when I open the app freshly but when I swipe to 2nd fragment and come back to first then it work correctly but at start/opening the app firstly then it shows wrong menu item btw I using setOffScreenPageLimit(4) this problem occurs when I use this method I hope anyone could solve this problem

I guess this is my situation I tried this ->

How to correctly inflate menus for an action bar from viewpager fragments

but it shouldn't work


Solution

  • I am giving you here full source code for your problem. Give it a try and hope it might help you. Create an options menu according to your requirement.

    Follow below steps

    1 - activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    2 - MainActivity.java

    public class ViewPagerActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewpager_activity);
    
        initViewPager();
    }
    
    private void initViewPager() {
        ViewPager2 viewPager = findViewById(R.id.viewPager);
        ViewpagerAdapter adapter = new ViewpagerAdapter(this);
        viewPager.setAdapter(adapter);
    
        // Add menu items without overriding methods in the Activity
        addMenuProvider(new MenuProvider() {
            @Override
            public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
                // Add menu items here
                switch (viewPager.getCurrentItem()) {
                    case 0:
                        getMenuInflater().inflate(R.menu.menu_one, menu);
                        break;
    
                    case 1:
                        getMenuInflater().inflate(R.menu.menu_two, menu);
                        break;
    
                    case 2:
                        getMenuInflater().inflate(R.menu.menu_three, menu);
                        break;
    
                    case 3:
                        getMenuInflater().inflate(R.menu.menu_four, menu);
                        break;
                }
            }
    
            @Override
            public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
                return false;
            }
        });
    }
    

    }

    3 - Your viewpager2 adapter

    public class ViewpagerAdapter extends FragmentStateAdapter {
    
        public ViewpagerAdapter(@NonNull FragmentActivity fragmentActivity) {
            super(fragmentActivity);
        }
    
        @NonNull
        @Override
        public Fragment createFragment(int position) {
            return MyFragment.newInstance(position);
        }
    
        @Override
        public int getItemCount() {
            return 4;
        }
    }
    

    4 - Your fragment

    public class MyFragment extends Fragment {
    
        private int fragmentPos = 0;
    
        public MyFragment(int fragmentPos) {
            this.fragmentPos = fragmentPos;
        }
    
        public static MyFragment newInstance(int fragmentPos) {
            Bundle args = new Bundle();
            MyFragment fragment = new MyFragment(fragmentPos);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_view, container, false);
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
            setHasOptionsMenu(true);
            AppCompatTextView label = view.findViewById(R.id.tvFragPos);
            label.setText("Current fragment index \n" + fragmentPos);
        }
    }
    

    Output

    1st Fragment option menu

    3rd Fragment option menu