0

I'm trying to let my HomeActivity extend BaseActivity (as suggested here) so I can have the same Navigation Drawer in every Activity I want. But I get a NullPointerException in the onCreate method of my HomeActivity. This is the code of BaseActivity:

import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    private String[] drawerListEntries;
    private ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {

        drawerListEntries = new String[] {"Bla bla", "Profile", "Home"};

        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_navigation_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.hello_world);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        //layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.drawer_list);
//        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
//        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawerListEntries));
//        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
//                R.layout.drawer_list_footer, null, false);
//        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                //map.drawerClickEvent(pos);
                String selectedValue = (String) drawerList.getAdapter().getItem(pos);
                Toast.makeText(getBaseContext(), selectedValue, Toast.LENGTH_SHORT).show();
            }
        });
    }

    @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);
    }
}

And this is the code of HomeActivity which extends BaseActivity:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.facebook.Session;

public class HomeActivity extends BaseActivity {

    TextView greeting;
    Button orderButton, deliverButton, logout;

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

        setContentView(R.layout.activity_home);


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.home, menu);
        //return super.onCreateOptionsMenu(menu);
        return true;
    }


}

I get a NullPointerException in:

super.onCreate(savedInstanceState); // HomeActivity

and when I click on that, it goes to:

drawerLayout.setDrawerListener(drawerToggle); // BaseActivity

Does anyone know how I can fix this?

Update:

drawer_list.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" >


    <ListView
        android:id="@+id/drawer_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="5dp"
        android:background="@android:color/transparent"
        android:cacheColorHint="@android:color/transparent"
        android:divider="#CCCCCC"
        android:dividerHeight="1dp"
        android:paddingLeft="2dp" />


</android.support.v4.widget.DrawerLayout>

and drawer_list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/drawer_list_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="12dp" 
        android:textSize="24sp" 
        android:layout_gravity="left"
        android:textColor="@color/belize_hole"
        android:fontFamily="sans-serif-light">
    </TextView>



</LinearLayout>
Community
  • 1
  • 1
Loolooii
  • 8,588
  • 14
  • 66
  • 90
  • It looks like you're trying to find the drawer view before you've set the content view. – daentech Feb 19 '14 at 22:57
  • @daentech but that answer was accepted and the poster claims that it works 100%... What would you suggest to do? – Loolooii Feb 19 '14 at 23:04
  • Does it work if you move the `setContentView(R.layout.activity_home);` from the HomeActivity into the BaseActivity, before the `drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);` line? – daentech Feb 19 '14 at 23:10
  • @daentech I just tried and that doesn't work. – Loolooii Feb 19 '14 at 23:13
  • Could you post your xml and the logcat output in the question, please? – daentech Feb 19 '14 at 23:15
  • @daentech I just updated my question. – Loolooii Feb 19 '14 at 23:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47904/discussion-between-daentech-and-loolooii) – daentech Feb 19 '14 at 23:21
  • Firstly, in the code you've shown you're not calling `super.onCreate(...)` in the `onCreate(...)` method of `BaseActivity` (which should be throwing an error anyway, or is that a typo?). Secondly, in the `onCreate(...)` method of `BaseActivity` you're using `findViewById(...)` to get your `DrawerLayout`. The problem is that you haven't set a content view at that point so that call will return `null`. – Squonk Feb 19 '14 at 23:51
  • Also - in `HomeActivity` you're setting your content view to activity_home.xml but in your update the layout you've shown is called drawer_list.xml. Unless the activity_home.xml uses merge or include for that file then your `DrawerLayout` is never going to be found. – Squonk Feb 20 '14 at 00:01
  • @Squonk Thank you. deantech already told me that in the chat. But thanks anyways. – Loolooii Feb 20 '14 at 00:06
  • Did you guys ever come up with a solution for this in chat? If so I'd like to see it posted please. I am running into the SAME EXACT problem. Thanks! – Rob Feb 28 '14 at 16:57
  • @Rob This did not work eventually. I ended up using one Fragment for the navigation drawer and I just put that fragment in any activity I want. Basically you make a Fragment with the list and drawer inside and put the fragment in your activity's layout file. This sounds more logical to me than the other way around actually. I've lost the link to that page though. – Loolooii Feb 28 '14 at 23:39
  • @Loolooii Why did it 'not work eventually'? Were there limitations to the solution you devised and had to came up with the implementation you mentioned as a result? – Kurt Wagner Aug 27 '14 at 21:49
  • @KurtWagner I barely use any Fragments in my app, except DialogFragments, so for me it was more logical to see the drawer as a fragment to use next to every activity I want. Android documentation wants me to have fragments which are 'opened' when a drawer opens. For someone using only activities there are not many tutorials. So the limitation: use fragments, otherwise you cannot do it the Android documentation way. I hope I'm making myself clear. – Loolooii Sep 01 '14 at 12:30

1 Answers1

2

Same issue in a few posts. I am new to android but solved it this way. Would love to hear if there is a better "right" way to do it. (yes, without fragments but I know I need to learn them eventually).

The problem appears that the base class is not aware of the layout. Not sure how or why it worked for others without having to do something like this.. but I am new to Android.

I was getting the same error and solved by passing my layout to the base via onCreate.

So in the base, I modified onCreate to be like this:

protected void onCreate(Bundle savedInstanceState, int resLayoutID)
{
    super.onCreate(savedInstanceState);
    setContentView(resLayoutID);

Then, from my new activity, I have this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.my_activity);

This code in my base now works instead of staying null:

drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.left_drawer);

btw, this result was suggested to me by a friend and it worked for me.

richaa
  • 71
  • 5