.getSupportActionBar not available in Fragment; workaround leads to NullPointerException on rotation
Solution 1
Cast your getActivity()
to ActionBarActivity
/AppCompatActivity
(depends what you are using) and you will have access to the support ActionBar
.
((AppCompatActivity)getActivity()).getSupportActionBar();
or
((ActionBarActivity)getActivity()).getSupportActionBar();
Use this code in onActivityCreated(...)
method instead of onAttach(...)
Solution 2
Now it should actually be:
((AppCompatActivity)getActivity()).setSupportActionBar();
because ActionBarActivity is deprecated.
But this is only if you must do this outside of an activity, where it's most commonly done.
Solution 3
Even though this answers is given very late it can help someone. We can directly call like following code
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("String");
It also works fine.
PattaFeuFeu
Updated on July 21, 2022Comments
-
PattaFeuFeu almost 2 years
Structure
(names of Activies/Fragments changed)
Based on some advice written in Android Programming: The Big Nerd Ranch Guide, I have the following structure:
MyListFragment extends ListFragment
MyListActivity extends SimpleFragmentActivity
SimpleFragmentActivity extends ActionBarActivity
MyListActivity.java
public class MyListActivity extends SingleFragmentActivity { @Override protected Fragment createFragment() { return new MyListFragment(); } }
SingleFragmentActivity.java
public abstract class SingleFragmentActivity extends ActionBarActivity { protected abstract Fragment createFragment (); @Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragmentContainer); if (fragment == null) { fragment = createFragment(); fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit(); } } }
After having outlined and programmed the basic functionality of my app (including Contextual Action Bar, navigation, …) I wanted to make sure that the app is as backwards compatible as possible without too much additional effort. Therefore, I started using the AppCompat (com.android.support:appcompat-v7:20+) ActionBar.
What baffled me right at the beginning was that—opposed to every tutorial or Android’s Developer guidelines I read—the getSupportActionBar method has never been available in Android Studio (I’m using Android Studio v0.8.2 and JRE 1.7_60). Whenever I type
getActivity().getSup
, the only suggestions I get aregetSupportFragmentManager
andgetSupportLoaderManager
.As a workaround, I create a member variable
ActionBar mActionBar
inMyListFragment
and initialise it:@Override public void onAttach (Activity activity) { super.onAttach(activity); mActionBar = ((ActionBarActivity) activity).getSupportActionBar(); }
That seemed to do the trick on either Android 4.4.4 (Moto G) and 2.3.4 (LG E-510)—the only devices I have available.
However—coming to the problem I have—on rotation the ActionBar assignment gets lost and the application crashes with a NullPointerException. Debugging the application and setting a breakpoint on the following line in
onCreate
:mActionBar.setTitle(R.string.title_activity_my_list);
I found out that mActionBar is null after the rotation. Placing said line in
onCreateView
didn’t help.What I tried
- Placing the initialisation of
mActionBar
inonAttach
onActivityCreated
-
onCreate
/onCreateView
right before .setTitle gets called
I’m out of ideas here and grateful for advice.
EDIT-0 (30.07.)
Exception being thrown (after editing according to Alex’ suggestion)
07-30 15:05:25.239 5049-5049/MYAPPNAME E/AndroidRuntime﹕ [Blue Error Handler] Make Debugging Report file for main java.lang.RuntimeException: Unable to start activity ComponentInfo{MYAPPNAME/MYAPPNAME.MYLISTACTIVITY}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1653) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1669) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838) at android.app.ActivityThread.access$1600(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3737) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at MYAPPNAME.MYLISTFRAGMENT.onCreate(MYLISTFRAGMENT.java:54) at android.support.v4.app.Fragment.performCreate(Fragment.java:1481) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:908) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103) at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1896) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:216) at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98) at MYAPPNAME.SingleFragmentActivity.onCreate(SingleFragmentActivity.java:22) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1617) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1669) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838) at android.app.ActivityThread.access$1600(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3737) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652) at dalvik.system.NativeStart.main(Native Method)
MyListFragment
line 54 (exception occured using either SingleFragmentActivity and ActionBarActivity as a cast)((SingleFragmentActivity) getActivity()).getSupportActionBar().setTitle(R.string .title_activity_my_list);
SingleFragmentActivity
lines 20-22:@Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState);
-
PattaFeuFeu almost 10 yearsAs much as I hoped it would, that didn’t solve it. I updated my question and added the exception’s stack trace.
-
PattaFeuFeu almost 10 yearsI had it in
onCreate()
before. Putting it inonActivityCreated()
seems to work. I’ll try changing occurrences throughout the app; should it work everywhere, I’ll accept your answer. Thanks so far! -
PattaFeuFeu almost 10 yearsIt worked. But shouldn’t getSupportActionBar() work “out of the box”?
-
Alex almost 10 yearsIt's working out of box, but since the getActivity return a generic Activity you have to upcast it for the desired class. Also be sure when using it you check if the getActivity() is an instance of the ActionBarActivity to avoid class cast exceptions
-
Ashokchakravarthi Nagarajan over 9 yearsActually I forgot to cast the activity to ActionBarActivity. Thanks Alex