سؤال

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 are getSupportFragmentManager and getSupportLoaderManager.

As a workaround, I create a member variable ActionBar mActionBar in MyListFragment 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 in
    • onAttach
    • 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);
هل كانت مفيدة؟

المحلول

Cast your getActivity() to ActionBarActivity/AppCompatActivity (depends what are you 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(...)

نصائح أخرى

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.

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.

Sometime it can be null value. So just add like this example.

Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).hide();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top