22

I have the following fragment in my application:

public class MyFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
  private MenuItem refresh = null;

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setHasOptionsMenu(true);

    //.....

    // NPE here
    refresh.setActionView(R.layout.indeterminate_progress_action);
    getActivity().getSupportLoaderManager().initLoader(0, null, this);
  }

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.refresh_menu, menu);
    refresh = (MenuItem) menu.findItem(R.id.menu_item_refresh);
  }

  @Override
  public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mAdapter.swapCursor(data);
    refresh.setActionView(null);
  }
}

Basically when the user starts the Activity I want to display a progress spinner, in the actionbar, until the loader completes. Prior to Android 4.2 everything worked fine. On Android 4.2 I get the following error:

11-24 13:37:14.811: E/AndroidRuntime(17850): Caused by: java.lang.NullPointerException
11-24 13:37:14.811: E/AndroidRuntime(17850):    at com.MyApp.library.fragments.MyFragment.onActivityCreated(TabFragment.java:65)

After adding some break point I realized onCreateOptionsMenu was getting called after onActivityCreated. Is there another life cycle event I can use? Is there a better was to achieve the desired effect?

Frohnzie
  • 3,559
  • 1
  • 21
  • 24
  • 2
    Um, why not move your `setActionView()` call to `onCreateOptionsMenu()`, then? And perhaps do it conditionally depending upon whether or not the load is done? – CommonsWare Nov 24 '12 at 19:07
  • Kinda works. Seems like `onCreateOptionsMenu` gets called after `onLoadFinished` too. Since I have tabs with multiple loaders `hasRunningLoaders` isn't useful in determining if load has finished. Guess I will have to use a Boolean value to track the state. – Frohnzie Nov 24 '12 at 20:17
  • 6
    Android issue: http://code.google.com/p/android/issues/detail?id=39721 – Frohnzie Nov 24 '12 at 20:20
  • Can you post full error? What line of code is 65? Also can you not just check for != null before using the object, I have fixed similar problems in onCreateOptionsMenu before. – Jared Burrows May 28 '13 at 06:21
  • http://stackoverflow.com/a/11379474/1847899 maybe this is your problem .. ? – Alexander Sidikov Pfeif Jun 17 '13 at 17:59
  • I have Same problem, onCreateOptionsMenu gets called after onResume on Marshmallow – Ersen Osman Nov 13 '15 at 12:38

1 Answers1

4

I've used onPrepareOptionsMenu in this way to achieve what you are trying to do. (not tested but should give you an idea.)

private boolean mIsLoading = true;

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    refresh = (MenuItem) menu.findItem(R.id.menu_item_refresh);
    if (!mIsLoading) {
        refresh.setActionView(null);
    }
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mAdapter.swapCursor(data);
    mIsLoading = false;
    getActivity().invalidateOptionsMenu();
}
JRomero
  • 4,878
  • 1
  • 27
  • 49
  • How come onPrepareOptionsMenu method return void; I think I just saw a pussy cat; scared my freaking mind – DJphy May 09 '16 at 08:24