Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: NavigationDrawer/multiple activities/same menu

What I am trying to do, is have a NavigationDrawer menu like this: NavigationDrawer

I've figured out how to change layouts when menu items are clicked, but how do I load a new activity without losing the menu?

My main question:

For example let's say one of my menu options takes you to a layout where there are some buttons that do something. I need to load an accompanying activity/class, that will handle the actions and functionality of that specific "page" in the App. If another menu option takes you to a layout with only an image, for example, that would be another activity without all that code that handles the functionality of the buttons, since there are no buttons in this screen.

I hope that makes sense! I followed many tutorials/videos online using several methods (Fragments etc.) but nothing quite answered my question.

like image 490
Lambros Avatar asked Mar 18 '16 23:03

Lambros


4 Answers

Thanks to the above answers I was able to do exactly what I wanted, here's exactly what I did for anyone looking for this in the future:

My activity_main.xml looks like this:

<!--When the DrawerLayout is the root layout, the first child-->
<!--of that layout is the contents of the main screen, and the-->
<!--second child is the contents of the menu-->

<!--First child layout-->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content_frame"/>

</LinearLayout>

<!--Second child layout-->
<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="start"
    app:headerLayout="@layout/navigation_drawer_header"
    app:menu="@menu/drawer_menu">

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

This is the standard DrawerLayout which pulls together all the bits and pieces for the NavigationDrawer menu. The important addition to this is the FrameLayout... bit to which I gave the ID content_frame. This is where all the other layouts used by other activities will be pushed/added/inflated.

My BaseActivity.java looks like this:

package com.example.test;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;

public class BaseActivity extends AppCompatActivity {

    DrawerLayout drawerLayout;
    ActionBarDrawerToggle actionBarDrawerToggle;
    Toolbar toolbar;

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

        NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_closed);
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                switch (item.getItemId()) {

                    case R.id.menu_home:
                        Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
                        startActivity(loadPlayer);
                        drawerLayout.closeDrawers();
                        break;

                }
                return false;
            }
        });

    }

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

        actionBarDrawerToggle.syncState();
    }

}

Now, within the onNavigationItemSelected method, there is a switch statement that handles what happens when each menu item is selected. This is the important bit:

Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
startActivity(anIntent);
drawerLayout.closeDrawers(); 

You need to replace "TheClassYouWantToLoad" with your own class. Now within this new class (which presumably requires some new UI elements to be loaded), you need the following:

public class TheClassYouWantToLoad extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

FrameLayout contentFrameLayout = (FrameLayout) findViewById(R.id.content_frame); //Remember this is the FrameLayout area within your activity_main.xml
getLayoutInflater().inflate(R.layout.the_layout_you_want_to_load, contentFrameLayout);
    }
}

and replace "the_layout_you_want_to_load" with the name of the Layout you want to load.

like image 127
Lambros Avatar answered Oct 25 '22 02:10

Lambros


From what I understand, you want the navigation drawer to be present in every activity. There are two methods:

  1. Use @Russell's answer. Make a main activity having a framelayout usually called content_frame which covers the whole activity. This activity has the code for the navigation drawer. On button click you can replace the contents of this layout with the layout of the desired fragment (i.e. either fragment with several buttons or say an image). So the elements in the drawer are all fragments. In the tutorials the fragments are called through getFragmentManager(). Check out the video series on navigation drawer by this guys, slidenerd: https://www.youtube.com/watch?v=K8hSIP2ha-g . Try to implement it as you are going along the video

  2. I personally prefer this method but it has its limitations. Create a baseactivity in which the code for the navigation drawer is. This has a framelayout usually called content_frame which covers the whole activity. The activities that need to have the drawer extend this baseactivity instead of appcompatactivity or activity. The layout inflation works like this in the oncreate: getLayoutInflater().inflate(R.layout.activity_this, contentFrameLayout); instead of setContentView. Here the activities are started through startActivity.

Cons of 2nd method:

a) The BaseActivity is destroyed and recreated every time the user changes activity.

b) The activity can extend only one class which by default become baseActivity

Pros of 2nd method:

a) You can maintain an activity stack

b) Each activity can have it's own configuration change rules and onsaveInstance rules.

c) These activities can have separate fragments, which use this activity for communication. Trying to do this in the first method would involve main activity implementing huge number of interfaces unnecessarily (you will learn about interfaces in inter-fragment communication)

like image 36
suku Avatar answered Oct 25 '22 03:10

suku


If you start a new activity, you will lose your menu because the new activity will cover the old activity. You need to use fragments for this. Think of fragments as activities that can live within another activity.

Use fragments, but add your UI elements to the activity layout outside of the FrameLayout (id: content_frame), then when you click on a menu item, your fragment transaction will only affect the content_frame FrameLayout, leaving all other layout items in place.

Hang in there, buddy, it only gets clearer from here... until you hit the next wall :D

I suggest this tutorial: https://www.udacity.com/course/viewer#!/c-ud853/l-1395568821

And this material: http://developer.android.com/training/implementing-navigation/nav-drawer.html

like image 35
Russell Elfenbein Avatar answered Oct 25 '22 01:10

Russell Elfenbein


You Have to Take On BaseActivity With Navigation Drawer as Normal Activity. Then after Extend this BaseActvity for all other activity.

Note: In BaseActivity You Have to Take Framelayout Instead of Your Include File like Below. GitHub Code Available Here

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/FullscreenTheme.AppBarOverlay">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:background="@color/colorPrimary"
        app:popupTheme="@style/FullscreenTheme.PopupOverlay"
        >

    </androidx.appcompat.widget.Toolbar>

</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/img_menu_prac_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_marginRight="@dimen/fab_margin"
    android:layout_marginBottom="16dp"
    app:srcCompat="@drawable/ic_practice_test"
    tools:ignore="VectorDrawableCompat"
    app:borderWidth="0dp"
    android:backgroundTint="@color/white"
    app:maxImageSize="58dp"
    />

For Complete Code Visit Github Project Click Here To Download Complete Project Here is Common Navigation Drawer

All activity Design

like image 33
Nimesh Patel Avatar answered Oct 25 '22 01:10

Nimesh Patel