Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionBarCompat + NavigationDrawerFragment doesnt work on android 4.0 and 4.1

Very strange problem! I created a new project through new project wizard in android studio. I chose to include support libraries for GridLayout, Fragments, NavigationDrawer and ActionBar. In next step I chose BlankActivity Template with NavigationDrawer navigation. Wizard nicely created my project and build it without any problem.

Problem is this, when you try to run it, it works fine on Android 4.3, 4.2 and 2.3.3 but it crashes on 4.0 and 4.1.

Stack trace:

10-30 13:11:31.024    2136-2136/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.navdrawer/com.navdrawer.MainActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
        at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
        at android.app.Activity.setContentView(Activity.java:1867)
        at android.support.v7.app.ActionBarActivity.superSetContentView(ActionBarActivity.java:208)
        at android.support.v7.app.ActionBarActivityDelegateICS.setContentView(ActionBarActivityDelegateICS.java:111)
        at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:76)
        at com.navdrawer.MainActivity.onCreate(MainActivity.java:37)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
            at android.app.ActivityThread.access$600(ActivityThread.java:130)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at com.navdrawer.MainActivity.onCreateOptionsMenu(MainActivity.java:82)
        at android.app.Activity.onCreatePanelMenu(Activity.java:2476)
        at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
        at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:224)
        at android.support.v7.app.ActionBarActivityDelegateICS.onCreatePanelMenu(ActionBarActivityDelegateICS.java:141)
        at android.support.v7.app.ActionBarActivity.onCreatePanelMenu(ActionBarActivity.java:199)
        at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onCreatePanelMenu(ActionBarActivityDelegateICS.java:280)
        at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:393)
        at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:747)
        at android.app.Activity.invalidateOptionsMenu(Activity.java:2595)
        at android.support.v4.app.ActivityCompatHoneycomb.invalidateOptionsMenu(ActivityCompatHoneycomb.java:29)
        at android.support.v4.app.FragmentActivity.supportInvalidateOptionsMenu(FragmentActivity.java:633)
        at android.support.v7.app.ActionBarActivity.supportInvalidateOptionsMenu(ActionBarActivity.java:170)
        at android.support.v4.app.Fragment.setHasOptionsMenu(Fragment.java:781)
        at com.navdrawer.NavigationDrawerFragment.onCreate(NavigationDrawerFragment.java:82)
        at android.support.v4.app.Fragment.performCreate(Fragment.java:1455)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:893)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
        at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1184)
        at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
... 24 mo

This is the onCreateOptionsMenu in fragment

 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // If the drawer is open, show the global app actions in the action bar. See also
        // showGlobalContextActionBar, which controls the top-left area of the action bar.
        if (mDrawerLayout != null && isDrawerOpen()) {
            inflater.inflate(R.menu.global, menu);
            showGlobalContextActionBar();
        }
        super.onCreateOptionsMenu(menu, inflater);
    }

This one is in the MainActivity

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.main, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }
like image 578
Mario Zderic Avatar asked Oct 30 '13 12:10

Mario Zderic


2 Answers

Just ran into this same exact issue. EXACT ISSUE.

The issue is that setHasOptionsMenu(true); is called in onCreate instead of onActivityCreated in the Fragment. Seems like a bug in the Wizard if you ask me.

To solve this, move the setHasOptionsMenu(true); call from onCreate() to onActivityCreated().

This will solve the problem. By the time the call gets to Activity#onCreateOptionsMenu the fragment instance will be instantiated.

like image 91
Donn Felker Avatar answered Nov 20 '22 20:11

Donn Felker


I resolved problem. Stack trace was tottally missleading to me...

Problem was as eee suggested in onCreateOptionsMenu() in activity...

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.main, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

somehow only on Android 4.1 and 4.0 mNavigationDrawerFragment is null although it's initialized in onCreate() so i put this

if(mNavigationDrawerFragment == null )
            mNavigationDrawerFragment = (NavigationDrawerFragment)
                    getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);

in both onCreate() and in onCreateOptionsMenu() method

like image 38
Mario Zderic Avatar answered Nov 20 '22 18:11

Mario Zderic