Search code examples
androidnullpointerexceptionnavigation-drawerpreferenceactivitydrawerlayout

PreferenceActivity with Navigation Drawer Throws Null Pointer Exception


I had a PreferenceActivity which was working fine. Then, I decided to add a navigation drawer to it, and edited the layouts according to my other activity layouts which also have working navigation drawers. However, after doing that, my PreferenceActivity stopped opening and started throwing a NPE on start. I can't even open that activity anymore. Problem is in onCreate, obviously, and also in an onClick method as stated in the logcat. Yet, there are two onClick's in this activities onCreate, and I'm not seeing how those result in a NPE, since they are the exact same in my other working activities. My layout xmls are seperated into 3 xmls according to the default DrawerLayout implementation. Without further due, here are the codes and xmls:

PreferenceActivity:

public class FirstYearCoursesActivity extends PreferenceActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private AppCompatDelegate mDelegate;
Toolbar toolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    getDelegate().installViewFactory();
    getDelegate().onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first_year_courses);
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar((toolbar));
    Window window = this.getWindow();
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.setStatusBarColor(this.getResources().getColor(R.color.colorPrimaryDark));
    addPreferencesFromResource(R.xml.prefs);
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view2);
    navigationView.setNavigationItemSelectedListener(this);
    View headerView = navigationView.getHeaderView(0);
    ImageButton logoutButton = (ImageButton) headerView.findViewById(R.id.logoutButton);
    logoutButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(FirstYearCoursesActivity.this, LoginActivity.class);
            startActivity(intent);
        }
    });
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
protected void onPause() {
    final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    final Handler handler = new Handler();
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                drawer.closeDrawer(GravityCompat.START);
            }
        }, 200);
        super.onPause();
    } else {
        super.onPause();
    }
}
private void setSupportActionBar(@Nullable Toolbar toolbar) {
    getDelegate().setSupportActionBar(toolbar);
}

private AppCompatDelegate getDelegate() {
    if (mDelegate == null) {
        mDelegate = AppCompatDelegate.create(this, null);
    }
    return mDelegate;
}

@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {

    String key = preference.getKey();
        switch (key) {
            case "math119":
                Intent intent = new Intent(FirstYearCoursesActivity.this, Math119Activity.class);
                startActivity(intent);
                break;
            default:
                Toast.makeText(this, "Other Click", Toast.LENGTH_SHORT).show();
                break;
        }

    return super.onPreferenceTreeClick(preferenceScreen, preference);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
   // to be filled
    int id = item.getItemId();

    if (id == R.id.nav_camera) {

    } else if (id == R.id.nav_gallery) {

    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }
    return true;
}
}

activity.xml:

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<include
    layout="@layout/app_bar_first_year_courses"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view2"
    android:layout_width="250dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer"
    android:background="#ffffffff"
    app:itemTextColor="#000000"
    app:itemTextAppearance="@style/TextAppearance.AppCompat.Body1"/>
</android.support.v4.widget.DrawerLayout>

app_bar.xml:

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.FirstYearCoursesActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay"/>

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_first_year_courses"/>

</android.support.design.widget.CoordinatorLayout>

content.xml:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.FirstYearCoursesActivity"
tools:showIn="@layout/app_bar_first_year_courses"
android:orientation="vertical">

</LinearLayout>

nav_header.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="140dp"
          android:background="@drawable/profilebanner"
          android:gravity="bottom"
          android:orientation="vertical"
          android:theme="@style/ThemeOverlay.AppCompat.Dark"
          android:id="@+id/header">

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/logoutButton"
    android:src="@drawable/ic_power_settings_new_white_18dp"
    android:background="#00ffffff"
    android:layout_alignParentTop="true"
    android:layout_alignParentEnd="true"
    android:layout_marginTop="30dp"
    android:layout_marginRight="10dp"/>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/headerClick"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingBottom="10dp"
    android:paddingTop="20dp">

    <ImageView
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:id="@+id/imageView"
        android:background="@drawable/onur"
        android:layout_centerVertical="true"
        android:layout_alignParentStart="false"
        android:layout_alignBottom="@+id/textView3"
        android:layout_marginBottom="-20dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Onur Çevik"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:id="@+id/textView2"
        android:textSize="13sp"
        android:layout_toRightOf="@+id/imageView"
        android:layout_marginLeft="25dp"
        android:layout_marginTop="45dp"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Environmental Engineering"
        android:textSize="11sp"
        android:layout_toRightOf="@+id/imageView"
        android:layout_marginLeft="25dp"
        android:layout_below="@+id/textView2"
        android:layout_alignParentStart="false"/>

</RelativeLayout>

</RelativeLayout>

prefs.xml:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="firstyearprefs">
<Preference
    android:title="Math-119"
    android:key="math119"/>
<Preference
    android:title="Math-120"
    android:key="math120"/>
<Preference
    android:title="Phys-105"
    android:key="phys105"/>
<Preference
    android:title="Phys-106"
    android:key="phys106"/>
<Preference
    android:title="Chem-107"
    android:key="chem107"/>
<Preference
    android:title="Eng-101"
    android:key="eng101"/>
<Preference
    android:title="Eng-102"
    android:key="eng102"/>
<Preference
    android:title="Ce-101"
    android:key="ce101"/>

</PreferenceScreen>

logcat:

02-08 02:10:35.415 30815-30815/com.theoc.proto E/AndroidRuntime: FATAL EXCEPTION: main
                                                             Process: com.theoc.proto, PID: 30815
                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setOnItemClickListener(android.widget.AdapterView$OnItemClickListener)' on a null object reference
                                                                 at android.preference.PreferenceScreen.bind(PreferenceScreen.java:143)
                                                                 at android.preference.PreferenceActivity.bindPreferences(PreferenceActivity.java:1419)
                                                                 at android.preference.PreferenceActivity.access$000(PreferenceActivity.java:123)
                                                                 at android.preference.PreferenceActivity$1.handleMessage(PreferenceActivity.java:230)
                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                 at android.app.ActivityThread.main(ActivityThread.java:5272)
                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)

EDIT:

One thing worth mentioning is that I triple checked the activity and it's adapter that leads to this PreferenceActivity on list item click. I reversed all my Drawer Layout implementations, and I was able to open this PreferenceActivity through parent activity. Navigation Drawer code, or layouts are the ones messing with it. I'm getting the listview.onclick(adapter) NPE because my list item click on parent activity goes to a null reference, which in this case it the PreferenceActivity itself. Also debug didn't show me anything null in PreferenceActivity's onCreate, except savedInstanceState.


Solution

  • I was able to reproduce the same NPE using your code and fixed it by replacing the addPreferencesFromResource call (note that it's deprecated) using a fragment instead as described in these threads:

    Android: Preference Fragment with a Navigation Drawer's Fragment

    What to use instead of "addPreferencesFromResource" in a PreferenceActivity?

    Although, on my version, the preferences view overlaps the toolbar and I am not sure what the activity layout should be to fix that, maybe it will be OK in yours.