Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I want to define a single nav drawer I can use throughout my application. I followed the instructions of the chosen answer here as my first approach: Same Navigation Drawer in different Activities

I made a few modifications, namely calling onCreateDrawer from inside an overridden onCreate. I updated my subsequent activity to extend DashboardActivity ("base activity" from the example). When I launch my second activity I get a null pointer exception complaining that the nav UI doesn't exist when onCreateDrawer tries to set the toggle listened on the drawer.

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.widget.DrawerLayout.setDrawerListener(android.support.v4.widget.DrawerLayout$DrawerListener)' on a null object reference

Here are the base (dashboard) and subsequent (log workout) activity - please ask if there is other code you want to see. The code for the UI of the drawer and associated activity are what came out of the box when creating a new Nav Drawer Activity in Android Studio.

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

        onCreateDrawer();

        Realm realm = Realm.getDefaultInstance();

        RealmQuery<Exercise> query = realm.where(Exercise.class);
        RealmResults<Exercise> result = query.findAll();
        Log.d(TAG, "There are " + result.size() + " exercises ready for use.");

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent logWorkoutIntent = new Intent(getApplicationContext(), LogWorkoutActivity.class);
                startActivity(logWorkoutIntent);
            }
        });

        //TODO: Remove this sign out button
        Button signOutButton = (Button) findViewById(R.id.button_sign_out);
        signOutButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseAuth.getInstance().signOut();
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
                Toast.makeText(getApplicationContext(), "Signed out", Toast.LENGTH_LONG).show();
            }
        });

        //TODO: Remove this data tester
        updateUserName();
    }

    //@Override
    protected void onCreateDrawer() {
        Log.d(TAG, "onCreateDrawer called");
        //super.onCreate(savedInstanceState);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

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

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        mDrawerLayout.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

...

-

LogWorkoutActivity.java
public class LogWorkoutActivity extends DashboardActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_log_workout);
        setContentView(R.layout.activity_log_workout);
        super.onCreateDrawer();
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        //getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
148 views
Welcome To Ask or Share your Answers For Others

1 Answer

I think you are missing a drawer with id drawer_layout in your activity_log_workout layout.

In order for this approach to work, you must have a DrawerLayout with id drawer_layout in all your activity layouts that should have the drawer.

I also noticed something peculiar with your code. In every activity that extends DashboardActivity you are first setting setContentView(R.id.activity_dashboard), then calling onCreateDrawer(), then you are changing the content view and creating the drawer again. I think this a very suboptimal approach.

I suggest you create a BaseDrawerActivity class to encapsulate the drawer creation and UI binding logic. Then you just extend it in the activities where you need a drawer. You can do it like this:

public abstract class BaseDrawerActivity extends AppCompatActivity {

    // move all your drawer related fields here

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

        setContentView(getLayoutResId());

        // the same method you have right now
        onCreateDrawer();
    }


    /*
     * Extending activities use this class to supply the 
     * id of their layout file. This way you can set the view 
     * only once and there is no need to create the drawer twice.
     */
    @LayoutResId
    public abstract int getLayoutResId();

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...