I am trying to set up the Android Nav Drawer with an action bar. I am having difficulty setting the icon for the Nav Drawer and generating all of the list items as well. Below is my code, I am currently generating a NullPointer Exception:
Crash:
--------- beginning of crash
04-20 18:02:03.690 13170-13170/com.sourcey.materialloginexample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sourcey.materialloginexample, PID: 13170
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sourcey.materialloginexample/com.troychuinard.fanpolls.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
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:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
at com.troychuinard.fanpolls.MainActivity.onCreate(MainActivity.java:71)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
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:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
MainActivity:
public class MainActivity extends AppCompatActivity implements HomePollsFragment.OnFragmentInteractionListener {
private Toolbar toolbar;
private Firebase mPollsRef;
private ViewPager mPager;
private ScreenSlidePagerAdapter mPagerAdapter;
private DateFormat mDateFormat;
private Date mDate;
private String mCurrentDateString;
private ValueEventListener v;
private String[] mPlanetTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.action_tool_bar);
setSupportActionBar(toolbar);
Firebase.setAndroidContext(this);
mPollsRef = FirebaseUtil.FIREBASE.child("Polls");
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
toolbar, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */) {
};
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
ArrayList<String> drawerTitleArray = new ArrayList<>();
drawerTitleArray.add(0, "TEST");
drawerTitleArray.add(1, "TEST 1");
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, drawerTitleArray));
// TODO: Add Fragment Code to check if savedInstanceState == null; add at Activity Level?
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
//set up viewpager for current day
mPager = (ViewPager) findViewById(R.id.home_polls_viewpager_fragment_container);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
//get current date to apply to Viewpager
mDateFormat = new SimpleDateFormat("MM-dd-yyyy");
mDate = new Date();
mCurrentDateString = mDateFormat.format(mDate);
// TODO: Checkn if AuthStateListenerNecessary
//Determine whether necessary to use an AuthStateListener here
// mUserRef.addAuthStateListener(new Firebase.AuthStateListener() {
// @Override
// public void onAuthStateChanged(AuthData authData) {
// if (authData == null) {
// Intent backToSignIn = new Intent(getApplication(), SignupActivity.class);
// startActivity(backToSignIn);
// finish();
// }
// }
// })
}
@Override
protected void onStart() {
super.onStart();
v = new ValueEventListener() {
//testing methodology of adding children
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
int pollsAvailable = (int) dataSnapshot.child(mCurrentDateString).getChildrenCount();
mPagerAdapter.setPollsAvailable(pollsAvailable);
Log.i("TAG", "There are " + String.valueOf(pollsAvailable) + " children in today's poll count.");
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
};
mPollsRef.addValueEventListener(v);
}
@Override
protected void onStop() {
super.onStop();
mPollsRef.removeEventListener(v);
}
@Override
public void onFragmentInteraction(Uri uri) {
}
class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
private int pollsAvailable = 0;
//fragment adapter constructor
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return HomePollsFragment.newInstance(position);
}
@Override
public int getCount() {
return pollsAvailable;
}
public void setPollsAvailable(int pollsAvailable) {
this.pollsAvailable = pollsAvailable;
this.notifyDataSetChanged();
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (mPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
}
XML:
<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"
android:orientation="vertical">
<LinearLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/action_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/actionRed">
</android.support.v7.widget.Toolbar>
<android.support.v4.view.ViewPager
android:id="@+id/home_polls_viewpager_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
<!-- The navigation drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
I do it like this:
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
This should solve the java.lang.NullPointerException.
"and generating all of the list items as well"
I cant see whats the problem here. Could you explain it a little bit?
The icon - Three horizontal lines in closed mode, a back arrow in opened mode with a nice smooth animation:
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
toolbar, /* nav drawer icon to replace 'Up' caret */
R.string.nav, /* "open drawer" description */
R.string.nav /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
if(extra == null){
toolbar.setTitle(title);
}else{
toolbar.setTitle(title + " - " + extra);
}
isOpen = false;
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
actionBar.setTitle(R.string.nav);
isNavReady = true;
isOpen = true;
}
};
drawerLayout.addDrawerListener(drawerToggle);
@Override
public boolean onOptionsItemSelected(MenuItem item){
return drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}