getSupportActionBar from inside of Fragment ActionBarCompat

If someone uses com.android.support:appcompat-v7: and AppCompatActivity as activity then this will work

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);

After Fragment.onActivityCreated(...) you'll have a valid activity accessible through getActivity().

You'll need to cast it to an ActionBarActivity then make the call to getSupportActionBar().

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);

You do need the cast. It's not poor design, it's backwards compatibility.


For those using kotlin,

(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)

While this question has an accepted answer already, I must point out that it isn't totally correct: calling getSupportActionBar() from Fragment.onAttach() will cause a NullPointerException when the activity is rotated.

Short answer:

Use ((ActionBarActivity)getActivity()).getSupportActionBar() in onActivityCreated() (or any point afterwards in its lifecycle) instead of onAttach().

Long answer:

The reason is that if an ActionBarActivity is recreated after a rotation, it will restore all Fragments before actually creating the ActionBar object.

Source code for ActionBarActivity in the support-v7 library:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
  • ActionBarActivityDelegate.createDelegate() creates the mImpl object depending on the Android version.
  • super.onCreate() is FragmentActivity.onCreate(), which restores any previous fragments after a rotation (FragmentManagerImpl.dispatchCreate(), &c).
  • mImpl.onCreate(savedInstanceState) is ActionBarActivityDelegate.onCreate(), which reads the mHasActionBar variable from the window style.
  • Before mHasActionBar is true, getSupportActionBar() will always return null.

Source for ActionBarActivityDelegate.getSupportActionBar():

final ActionBar getSupportActionBar() {
    // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
    // could change after onCreate
    if (mHasActionBar || mOverlayActionBar) {
        if (mActionBar == null) {
            ... creates the action bar ...
        }
    } else {
        // If we're not set to have a Action Bar, null it just in case it's been set
        mActionBar = null;
    }
    return mActionBar;
}