从DrawerActivity继承(ActionBarDrawerToggle)

时间:2014-10-30 10:13:52

标签: android

我有一个DrawerActivity,它实现了ActionBarDrawerToggle。我希望我的主类继承这个类(当然还有其他类),所以我不必在每个活动中实现抽屉切换。

我在这一行得到一个NullPointerException

drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.app_name, R.string.app_name);

错误日志:

10-30 11:08:14.703: E/AndroidRuntime(6831): FATAL EXCEPTION: main
10-30 11:08:14.703: E/AndroidRuntime(6831): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.app.android/net.app.android.TestActivity}: java.lang.NullPointerException
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread.access$700(ActivityThread.java:134)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.os.Looper.loop(Looper.java:137)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread.main(ActivityThread.java:4867)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at java.lang.reflect.Method.invokeNative(Native Method)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at java.lang.reflect.Method.invoke(Method.java:511)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at dalvik.system.NativeStart.main(Native Method)
10-30 11:08:14.703: E/AndroidRuntime(6831): Caused by: java.lang.NullPointerException
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.internal.app.WindowDecorActionBar.getDecorToolbar(WindowDecorActionBar.java:248)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.internal.app.WindowDecorActionBar.init(WindowDecorActionBar.java:201)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.internal.app.WindowDecorActionBar.<init>(WindowDecorActionBar.java:176)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarActivityDelegateBase.createSupportActionBar(ActionBarActivityDelegateBase.java:156)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarActivityDelegate.getSupportActionBar(ActionBarActivityDelegate.java:123)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarActivityDelegate.getActionBarThemedContext(ActionBarActivityDelegate.java:251)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarActivityDelegate$ActionBarDrawableToggleImpl.getActionBarThemedContext(ActionBarActivityDelegate.java:279)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarDrawerToggle.<init>(ActionBarDrawerToggle.java:222)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.support.v7.app.ActionBarDrawerToggle.<init>(ActionBarDrawerToggle.java:150)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at net.app.android.DrawerActivity.onCreate(DrawerActivity.java:19)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at net.app.android.TestActivity.onCreate(TestActivity.java:12)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.Activity.performCreate(Activity.java:5047)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
10-30 11:08:14.703: E/AndroidRuntime(6831):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)
10-30 11:08:14.703: E/AndroidRuntime(6831):     ... 11 more

DrawerActivity

public class DrawerActivity extends ActionBarActivity {
    DrawerLayout drawerLayout;
    ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.app_name, R.string.app_name);

        drawerLayout.setDrawerListener(drawerToggle);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }

}

测试活动

public class TestActivity extends DrawerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_test);
        super.onCreate(savedInstanceState);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.test, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

activity_test

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">


            <TextView
                android:id="@+id/helloWorld"
                android:text="Hello World"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

    </FrameLayout>
    <include layout="@layout/activity_drawer"/>
</android.support.v4.widget.DrawerLayout>

activity_drawer

<?xml version="1.0" encoding="utf-8"?>
<!-- The navigation drawer -->
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/left_drawer"
    android:layout_width="220dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#a6a6a6"/>

修改 当我将setContentView(R.layout.activity_test);放入我的DrawerActivity并将其设置为启动器活动时,一切正常。怎么可能?我在setContentView(R.layout.activity_test);之前在我的TestActivity中调用了super.onCreate(),所以应该没有问题,对吧?

2 个答案:

答案 0 :(得分:2)

ActionBarActivity具有onPostCreate方法,该方法在onCreate之后立即调用。尝试将此代码从DrawerActivity.onCreate移至DrawerActivity.onPostCreate

    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.app_name, R.string.app_name);

    drawerLayout.setDrawerListener(drawerToggle);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

将TestActivity.onCreate更改为:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
}

答案 1 :(得分:0)

onCreate中的DrawerActivity你的setContentView(R.layout.activity_drawer); ?

更新的 对不起,我完全被误解,但你的做法是完全错误的。 如果你想在每个扩展DrawerActivity的活动中都有一个抽屉式挡板,唯一要做的就是把这个部分留空:

<!-- The main content view -->
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

并在DrawerActivity中创建一个抽象方法,如下所示:

public abstract Fragment getDefaultFragment();

并在DrawerActivity onCreate中使用它来替换@ + id / content_frame的内容。 但是activity_test必须是DrawerActivity的内容。