How to create a class with a Navigationdrawer to use in multiple Activities?

Asked

Viewed 1,139 times

2

I started studying Android development a little while ago, I saw that to use a Navigationdrawer the recommended is to use fragments to change a Framelayout in the main Activity, but in the new activities that create, did not want to have to put all the code of the Navigationdrawer again, wanted to know how to create a menu to use in any one.

Does anyone have any tips for me?

EDIT:

Mainactivity.java

public class MainActivity extends GenericActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setUpDrawerLayout();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Genericactivity.java

public class GenericActivity extends AppCompatActivity {

    protected DrawerLayout drawerLayout;
    protected Toolbar toolbar;
    protected boolean drawerLayoutEnable;
    protected NavigationView navigationView;
    protected ActionBarDrawerToggle toggle;

    protected void setUpDrawerLayout(){
        this.drawerLayoutEnable = true;

        toolbar = (Toolbar)findViewById(R.id.toolbar);
        if(toolbar !=null){
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);

            drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
            setUpDrawerToggle();
            setUpNavigationView();
        }
    }

    private void setUpNavigationView() {
        navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener((NavigationView.OnNavigationItemSelectedListener) this);
    }

    private void setUpDrawerToggle(){
        toggle = new ActionBarDrawerToggle(
                this, 
                drawerLayout, 
                toolbar, 
                R.string.navigation_drawer_open, 
                R.string.navigation_drawer_close);
        drawerLayout.setDrawerListener(toggle);
        toggle.syncState();
    }

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

activity_generic.xml

<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/activity_base"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.example.rafael.elite.BaseActivity">

    <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>

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout" //Seria este o drawer_layout que eu tenho que referenciar?
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:paddingTop="24dp"
            app:headerLayout="@layout/nav_drawer_header"
            app:menu="@menu/menu_generic_activity" />

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

  • Take a look at this OS reply: http://stackoverflow.com/a/19451842/5165061

1 answer

2


Well, that was a question that I faced when I decided to implement Navigationdrawer in my app as well, mainly because I would like to have activities in which I use it and other activities that I don’t use it. And mainly, I did not want to duplicate code by the classes, so after researching in several tutorials I adapted and arrived at this result below, in summary but you will understand the concept.

I created a Genericactivity where all other activities of my application will extend it:

public abstract class GenericActivity extends AppCompatActivity {
    protected DrawerLayout drawerLayout;
    protected ActionBarDrawerToggle drawerToggle;
    protected NavigationView navigationView;
    protected NavigationViewMenuHandler navigationMenuHandler;
    //Com essa variável eu valido se a activity possui o NavigationDrawer
    //para realizar determinadas ações, ou não.
    protected boolean drawerLayoutEnable;

    //esse método é chamado pelas activities que extendem esta classe
    //e desejam ter um NavigationDrawer.
    protected void setUpDrawerLayout() {
        this.drawerLayoutEnable = true;

        //Toda a lógica de criação do NavigationDrawer vai neste método
        //Atualize com suas regras caso necessário
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_black_36dp);
            actionBar.setDisplayHomeAsUpEnabled(true);

            drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            setUpDrawerToggle(); //configura o DrawerToggle
            setUpNavigationView(); //configura a NavigationView
        }
    }

    //Métodos private setUpDrawerToggle() e setUpNavigationView()
}

Now all activities of my application that wish to have the same Navigationdrawer configured extend Genericactivity and just call the method setUpDrawerLayout() in the onCreate().

For example:

public class AppFootActivity extends GenericActivity {

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

    setContentView(R.layout.app_activity);
        //Chamo a configuração do NavigationDrawer. Caso eu não queira que
        //minha activity tenha um, basta não chamá-lo.
        setUpDrawerLayout();

        //Demais códigos da activity
    }

}

This same logic can be applied to other components like Toolbar.

I took into consideration that you already know how to implement the Navigationdrawer and have only the doubt of how to do it in various activities.

Hug.

  • Julio, thank you very much, I’m following your answer but I have a problem. When I try to run the app, I get the following error: java.lang.Runtimeexception: Unable to start Activity Componentinfo{br.com.rafael.testenavigationdrawer/br.com.rafael.testenavigationdrawer.Mainactivity}: 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&#xA;&#xA;O erro acontece quando chamo o método SetupDrawerToggle() I edited the question and put my files

  • From what I could notice your drawerLayout is null at the time it will call the drawerLayout.toggle() method. Did you implement xml containing Drawerlayout? Note in the code it calls findViewById(R.id.drawer_layout) trying to find the view with this id.

  • I think I am implementing the correct, I added the xml of Genericactivity, if possible take a look and tell me what you think.

  • Change your xml by leaving Drawerlayout as the main view. Leaving <Drawerlayout> <Appbarlayout><Toolbar/></Appbarlayout> <Navigationview/> </Drawerlayout>.

  • I did, I just forgot to post the answer, the problem with Nullpointerexcption was that I had set Drawer and Toolbar in the xml file of the Genericactiviy class, Only then I realized that she should not have the file and that Toolbar and Drawer should be defined in the Activity xml that extends the Genericactivity class. Now the only question, how to do so that when I click on the item of the navigation Drawer corresponding to Activity in which I am, it is not reloaded but only close the navigationDrawer?

  • You can create another question in the stack by better exemplifying your case, it’s hard to help with the comments. However, I believe that the answer you are looking for is on this page: https://guides.codepath.com/android/Fragment-Navigation-Drawer

  • I have already got the answer, but thank you very much.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.