1

I have an application with two activities hosting fragments. My main activity hosts a single fragment, and that fragment is able to define and inflate a menu that goes in the toolbar, no problem.

In the second activity, though, which uses a FragmentStatePagerAdapter to allow horizontal scrolling between items, my fragment does not seem able to define the menu in the toolbar.

Checks:

  • My whole app is set to use a theme (android:theme="@style/AppTheme") based on Theme.AppCompat.Light.DarkActionBar.
  • My fragment extends android.support.v4.app.Fragment
  • setHasOptionsMenu(true); is called from the fragment's onCreate() method
  • the hosting activity extends AppCompatActivity and does not implement a toolbar menu itself
  • my fragment overrides void onCreateOptionsMenu(Menu, MenuInflater), but this method seems to never be called

You can have a look at the commit that is supposed to add that menu on GitHub. (Or even look at any part of the code that might be a cause of error.)

Here are the big lines:

CrimeFragment.java:

public class CrimeFragment extends Fragment {

    // ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate()");
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        UUID id = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
        Log.d(TAG, String.format("Crime id in intent's extra: %s", id.toString()));
        mCrime = CrimeLab.get(getActivity()).getCrime(id);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        Log.d(TAG, "onCreateOptionsMenu()"); // <= Never shows in the Android Monitor
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.fragment_crime, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_item_delete_crime:
                CrimeLab.get(getActivity()).deleteCrime(mCrime);
                getActivity().finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    // ...
}

Is there something I'm doing wrong here?

David Stosik
  • 879
  • 9
  • 17
  • You should use onPrepareOptionMenu() method to use menus in fragment. – Divyesh Patel Nov 04 '16 at 15:11
  • @Divyesh Thank you. Unfortunately, even after trying to override that method (with an `s`: `onPrepareOptionsMenu`) in my fragment, it does not get called either... – David Stosik Nov 04 '16 at 15:20
  • Your second Activity defines menu item or not? – Divyesh Patel Nov 04 '16 at 15:22
  • @Divyesh No, the activity does nothing to the menu. – David Stosik Nov 04 '16 at 15:24
  • Activity must define OncreateOption menu. You should define menu item in your activity and just use sethasOptionMenu(true) in your fragments. – Divyesh Patel Nov 04 '16 at 15:26
  • @Divyesh Why is this required, whereas my main activity does not defines `onCreateOptionsMenu` and the fragment is able to do so? Android documentation says both activities and fragments can define menu items, here: https://developer.android.com/guide/topics/ui/menus.html#options-menu – David Stosik Nov 04 '16 at 15:39
  • I think you forgot to override OncreateView() in fragment. Add sethasOptionMenu in that method, and check log. – Divyesh Patel Nov 04 '16 at 15:46
  • @Divyesh I tried that too, no success... – David Stosik Nov 04 '16 at 15:51
  • http://stackoverflow.com/questions/30721664/android-toolbar-adding-menu-items-for-different-fragments – Divyesh Patel Nov 04 '16 at 15:52
  • @Divyesh Thanks, but unfortunately, none of the answers over there helped me solving my problem. – David Stosik Nov 05 '16 at 01:23
  • Can u tried to Initialize toolbar in hosting activity? – Divyesh Patel Nov 05 '16 at 03:44
  • @Divyesh Thank you very much for your help, I really appreciate. Unfortunately again, trying to setup the toolbar menu in the hosting activity, even though it worked, was not what I wanted. I finally found the fix to my problem anyway, as you can find in the answer post I wrote below: http://stackoverflow.com/a/40434825/2341409 – David Stosik Nov 05 '16 at 04:42

1 Answers1

0

Alright, it took me the time, but I finally found what was wrong with my code. This was a bit tricky.

In an earlier change, I overrode FragmentStatePagerAdapter#setPrimaryItem() in the hosting activity, in order to be informed every time the user switches between pages.

Unfortunately, in that override, I forgot to call super, and that's what was confusing the application, apparently.

I just had to add that call to super, and my menu item suddenly started to show up.

public class CrimePagerActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crime_pager);
        // ...

        FragmentManager fragmentManager = getSupportFragmentManager();
        mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
            // ...

            @Override
            public void setPrimaryItem(ViewGroup container, int position, Object object) {
                super.setPrimaryItem(container, position, object); // <= This line was missing
                Crime crime = mCrimes.get(position);
                mChangedCrimeIds.add(crime.getId());
            }
        });
        mViewPager.setCurrentItem(CrimeLab.get(this).getPosition(crimeId));
    }
    // ...
}
David Stosik
  • 879
  • 9
  • 17
  • I override setPrimaryItem() method on my custom viewpager but still its not working Do you have any other idea? – Himadri Jun 11 '19 at 06:03