Question

I'm working with ActionBarSherlock, I need to change some icons on the action bar when the user does some stuff. In order to that I have to save the action bar for later usage :

private Menu actionBarMenu;

...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.map_activity_menu, menu);
    actionBarMenu = menu;
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    actionBarMenu.findItem(R.id.follow_my_position).setIcon(R.drawable.toolbar_myposition_active);
}

Okay ! Here's where the problems begin. When I rotate the screen, I get a NullPointerException on actionBarMenu.
I know... I didn't save it before the screen was rotated, so normally I would go to onSaveInstanceState and save my Menu there, except the actionBarMenu is an interface... More specifically, the interface com.actionbarsherlock.view.Menu and I can't modify it so that it implements Parcelable or Serializable.

So how can I save an interface in the bundle ?

Was it helpful?

Solution 2

You can't. However, you can still retain your member variable on an orientation change by adding the following code to your activity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Object last = getLastNonConfigurationInstance();
    if (last != null && last instanceof Menu) {
        actionBarMenu = (Menu) last;
    }
}

// for FragmentActivity it is onRetainCustomNonConfigurationInstance
public Object onRetainNonConfigurationInstance() {
    return actionBarMenu;
};

OTHER TIPS

You should not keep reference to your action bar during configuration changes. After screen rotate, Android will recreate your activity and all UI references should be released, otherwise you will introduce reference leak.

Why dont you get your actionBarMenu reference again inside boolean onCreateOptionsMenu, after activity rotates?

You don't. You don't save the interface. You save some String, or boolean, or integer, representing the action the user did. Then you check this value and change the menu again.

Does this work before the rotate? Because a rotation just recreates the entire activity - i.e. it goes through the whole creation process again. So, I'm not sure that the recreation is your problem, because onCreateOptionsMenu(Menu menu); should be called again, anyway.

Are you sure that your actionBarMenu.findItem(R.id.follow_my_position) is returning correctly? Instead of handling it how your currently are - why not just...not store the menu and check the clicked menu item instead?

For example:

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
     switch(item.getItemId()){
         case R.id.follow_my_position:
             item.setIcon(R.drawable.toolbar_myposition_active);
     }
}

or if that's not what you're looking for, check that your findItem() call finds the item:

MenuItem item = actionBarMenu.findItem(R.id.follow_my_position);
if(item != null){
    item.setIcon(R.drawable.toolbar_myposition_active);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top