我有一个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()
,所以应该没有问题,对吧?
答案 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的内容。