LandScape模式中的ActionBarDrawerToggle.syncState()异常

时间:2016-01-23 01:26:11

标签: android android-fragments android-navigation-drawer

我的HomePage活动包含一个FrameLayout for Fragments和一个工具栏,上面有一个导航抽屉。启动应用程序后,HomeFragment将被置于框架布局中。导航抽屉工作得很好。当我转动手机时,我得到以下例外:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.markf.appname/com.markf.appname.HomePage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBarDrawerToggle.syncState()' on a null object reference

.....

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBarDrawerToggle.syncState()' on a null object reference

为什么在横向模式下抛出此异常?

这是我的Manifest文件,它实现了一个没有ActionBar的样式:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.markfeldman.boof">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme.NoActionBar"
    android:name="non_activity.ParseApplication">
    <activity android:name=".HomePage" />
    <activity android:name=".MainLoginActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

这是样式资源文件:

<resources>

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionOverflowButtonStyle">@style/MyActionButtonOverflow</item>
    <item name="colorPrimary">@color/toolBarBackground</item>
    <item name="colorPrimaryDark">@color/toolBarText</item>
</style>

<style name="MyActionButtonOverflow" parent="@android:style/Widget.Holo.Light.ActionButton.Overflow">
    <item name="android:src">@drawable/ic_list_black_24dp</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="MyOverflowStyle" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:colorBackground">@color/toolBarBackground</item>
    <item name="android:textColorPrimary">@color/toolBarText</item>
</style>

<style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <!-- Used for the buttons -->
    <item name="colorAccent">#0D3B66</item>
    <!-- Used for the title and text -->
    <item name="android:textColorPrimary">#000000</item>
    <!-- Used for the background -->
    <item name="android:background">#FFF176</item>
</style>

这是我的主页活动:

public class HomePage extends AppCompatActivity implements HomeFragment.OnClickedListener {
private FragmentTransaction ft;
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
String[] drawerListItems;
private Fragment fragment;

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

    if (findViewById(R.id.fragment_container) != null) {
        if (savedInstanceState != null) {
            return;
        }
        HomeFragment firstFragment = new HomeFragment();

        firstFragment.setArguments(getIntent().getExtras());

        getFragmentManager().beginTransaction()
                .add(R.id.fragment_container, firstFragment).commit();
    }

    Toolbar myToolbar = (Toolbar) findViewById(R.id.toolBarHome);
    drawerLayout = (DrawerLayout)findViewById(R.id.homePageDrawer);
    drawerList = (ListView)findViewById(R.id.homePageList);
    drawerListItems = getResources().getStringArray(R.array.activities);
    drawerList.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,drawerListItems));
    drawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            switch (position) {
                case 0: {
                    fragment = new HomeFragment();
                    break;
                }
                case 1: {
                    break;
                }
                case 2: {
                    break;
                }

            }
            ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fragment_container,fragment);
            ft.addToBackStack(null);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            ft.commit();
            drawerLayout.closeDrawer(drawerList);
        }
    });
    drawerToggle = new ActionBarDrawerToggle(this,drawerLayout,myToolbar,R.string.drawer_open,R.string.drawer_close)
    {
        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            invalidateOptionsMenu();
            syncState();
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            invalidateOptionsMenu();
            syncState();
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);
    setSupportActionBar(myToolbar);
    myToolbar.setLogo(R.drawable.happy_dog_icon);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);
    drawerToggle.syncState();
}

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

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:{
            if (drawerLayout.isDrawerOpen(drawerList)){
                drawerLayout.closeDrawer(drawerList);
            }else{
                drawerLayout.openDrawer(drawerList);
            }
            return true;
        }case R.id.infoActionBar:{
            Toast.makeText(getApplicationContext(), "Hey", Toast.LENGTH_LONG).show();
        }
        default:return super.onOptionsItemSelected(item);
    }
}

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

@Override
public void buttonClicked(View v) {
    switch (v.getId()){
        case R.id.logoutButton:{
            Intent i = new Intent(HomePage.this, MainLoginActivity.class);
            startActivity(i);
            finish();
        }
    }
}

这是碎片:

public class HomeFragment extends Fragment implements View.OnClickListener {
private Button logoutButton;
private ParseUser user;
public OnClickedListener listener;


static interface OnClickedListener{
    public void buttonClicked(View v);
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    this.listener = (OnClickedListener)activity;
}

public HomeFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home, container, false);

    logoutButton = (Button)view.findViewById(R.id.logoutButton);
    logoutButton.setOnClickListener(this);

    return view;
}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.logoutButton:{
            user.logOut();
            listener.buttonClicked(v);
            break;
        }
    }
}}

有人可以解释为什么我得到这个例外吗?谢谢。

1 个答案:

答案 0 :(得分:1)

大概您的横向布局包含ID为ViewGroup的{​​{1}},因此执行将进入第一个fragment_container块。轮播到横向后,if将不会为空,并且执行将进入savedInstanceState块,您将ifonCreate()返回而未实例化ActionBarDrawerToggle,但是,您仍然在syncState()中调用onPostCreate(),而不先检查它是否为空。