Mismo cajón de navegación en diferentes actividades

206

Hice un cajón de navegación funcional como se muestra en el tutorial en el sitio web developer.android.com . Pero ahora, quiero usar un cajón de navegación, que creé en NavigationDrawer.class para múltiples actividades en mi aplicación.

Mi pregunta es, si alguien aquí puede hacer un pequeño tutorial, que explica cómo usar un cajón de navegación para múltiples actividades.

Lo leí primero en esta respuesta Android Navigation Drawer en múltiples actividades

pero no funcionó en mi proyecto

public class NavigationDrawer extends Activity {
public DrawerLayout drawerLayout;
public ListView drawerList;
private ActionBarDrawerToggle drawerToggle;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {

        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.app_name);
        }

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

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

    layers = getResources().getStringArray(R.array.layers_array);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    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, android.R.id.text1,
            layers));
    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);
        }
    });
}

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

En esta actividad quiero tener el cajón de navegación, así que extiendo 'NavigationDrawer' y en algunas otras actividades quiero usar el mismo cajón de navegación

  public class SampleActivity extends NavigationDrawer {...}

No se que cambiar ...

MEX
fuente
1
Puedes encontrar los ejemplos aquí .
Naddy
1
puede encontrar en: stackoverflow.com/questions/33009469/…
varotariya vajsi el

Respuestas:

188

Si desea un cajón de navegación, debe usar fragmentos. Seguí este tutorial la semana pasada y funciona muy bien:

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

También puede descargar un código de muestra de este tutorial para ver cómo puede hacer esto.


Sin fragmentos:

Este es su Código de Actividad Base:

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

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

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

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

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

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        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, android.R.id.text1,
                layers));
        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);
            }
        });
    }

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

Todas las demás actividades que necesitan tener un cajón de navegación deben extender esta actividad en lugar de la actividad en sí misma, por ejemplo:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Editar:

Experimenté algunas dificultades, así que aquí hay una solución si obtienes NullPointerExceptions. En BaseActivity cambie la función onCreate a protected void onCreateDrawer(). El resto puede permanecer igual. En las Actividades que extienden BaseActivity, coloque el código en este orden:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

Esto me ayudó a solucionar mi problema, ¡espero que ayude!

Así es como puede crear un cajón de navegación con múltiples actividades, si tiene alguna pregunta, no dude en preguntar.


Edición 2:

Como dijo @GregDan BaseActivity, también puede anular setContentView()y llamar aCreateDrawer allí:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}
Kevin van Mierlo
fuente
77
No quiero usar actividades sobre fragmentos, solo quiero usar diferentes actividades que usan el mismo cajón de navegación. Quiero actividad, porque allí puedo usar diferentes tipos de diseño, como la vista deslizante, la vista de mapa ...
MEX
135
Tener solo una actividad puede ser una tarea desalentadora para cualquier aplicación bastante compleja. El uso de Actividades le brinda muchas cosas gratuitas del sistema, por lo que es un punto válido cómo usar múltiples Actividades. No me puedo imaginar una actividad que maneje la comunicación entre cualquier cantidad de combinaciones de fragmentos, simplemente no funcionará.
slott
1
Lamento que me haya tomado tanto tiempo responder. Edité mi respuesta. Creo que este es el tutorial que estabas buscando. Espero que esto ayude.
Kevin van Mierlo
2
@KevinvanMierlo, ¿puede decirme qué quiere decir con: R.id.drawer_layout debe estar en cada actividad con exactamente la misma identificación? Porque hice exactamente lo que dijiste aquí y obtengo una NullPointerException en el método onCreate () de la Actividad que extiende esta Actividad Base ..
Loolooii
1
@KevinvanMierlo por cierto, ¿creo que olvidaste estas 2 líneas? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii
34

He encontrado la mejor implementación. Está en la aplicación Google I / O 2014 .

Usan el mismo enfoque que el de Kevin. Si puede abstraerse de todas las cosas innecesarias en la aplicación de E / S, podría extraer todo lo que necesita y Google le asegura que es un uso correcto del patrón del cajón de navegación. Cada actividad opcionalmente tiene un DrawerLayoutcomo su diseño principal. La parte interesante es cómo se realiza la navegación a otras pantallas. Se implementa de BaseActivityesta manera:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

Esto difiere de la forma común de reemplazar el fragmento actual por una transacción de fragmento. Pero el usuario no detecta una diferencia visual.

Jinete del viento
fuente
Esto ^ No puedo entender cómo comienzan nuevas actividades y funciona perfectamente. Es una gran aplicación para trabajar.
hitch.united
@ hitch.united Eso se debe a que usan muchos fragmentos y solo algunas actividades.
Joaquin Iurchuk
@ hitch.united probablemente anulen la animación de la actividad con overridePendingTransitions.
EpicPandaForce
¿Carga fragmentos en lugar de subclasificar actividades?
Vikas Pandey
Aquí está el archivo de octubre de 2014: github.com/google/iosched/blob/…
denvercoder9
8

Entonces, esta respuesta se retrasa unos años, pero alguien puede apreciarla. Android nos ha dado un nuevo widget que facilita el uso de un cajón de navegación con varias actividades.

android.support.design.widget.NavigationView es modular y tiene su propio diseño en la carpeta del menú. La forma en que lo usa es envolver los diseños xml de la siguiente manera:

  1. Root Layout es un android.support.v4.widget.DrawerLayout que contiene dos elementos secundarios: uno <include ... />para el diseño que se está envolviendo (ver 2) y un android.support.design.widget.NavigationView.

    <android.support.v4.widget.DrawerLayout
        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/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    <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:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

nav_header_main es solo un LinearLayout con orientación = vertical para el encabezado de su Navegación Drawar.

activity_main_drawer es un menú xml en su directorio res / menu. Puede contener elementos y grupos de su elección. Si utiliza la Galería de AndroidStudio, el asistente creará uno básico para usted y podrá ver cuáles son sus opciones.

  1. El diseño de la barra de aplicaciones generalmente es ahora un android.support.design.widget.CoordinatorLayout y esto incluirá dos hijos: un android.support.design.widget.AppBarLayout (que contiene un android.support.v7.widget.Toolbar) y un <include ... >para Su contenido real (ver 3).

    <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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="yourpackage.MainActivity">
    
     <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>
    
    <include layout="@layout/content_main" />

  2. El diseño del contenido puede ser el diseño que desee. Este es el diseño que contiene el contenido principal de la actividad (sin incluir el cajón de navegación o la barra de aplicaciones).

Ahora, lo bueno de todo esto es que puede ajustar cada actividad en estos dos diseños, pero que su NavigationView (consulte el paso 1) siempre apunte a activity_main_drawer (o lo que sea). Esto significa que tendrá el mismo (*) Navegador de navegación en todas las actividades.

  • No serán la misma instancia de NavigationView pero, para ser justos, eso no fue posible incluso con la solución BaseActivity descrita anteriormente.
jwehrle
fuente
stackoverflow está cortando algunos de los corchetes xml adjuntos, pero todo lo importante está ahí.
jwehrle
pero, ¿cómo se trata la funcionalidad como botones? debes escribir el mismo código en cada actividad?
Laur89
Sí, porque estas son instancias separadas. Sin embargo, puede hacer una superclase para que sus actividades se extiendan y poner ese código allí una vez.
jwehrle
@jwehrle, ¿puedes escribir un ejemplo sobre cómo hacer una superclase para nuestras actividades?
CDrosos
La clase abstracta pública MyBaseActivity extiende AppCompatActivity implementa NavigationView.OnNavigationItemSelectedListener {// implementa lo siguiente: Anular public boolean onNavigationItemSelected (elemento @NonNull MenuItem) {}} clase pública MyActivity extiende MyBaseActivity {}
jwehrle
7

La forma más fácil de reutilizar un cajón de navegación común entre un grupo de actividades

app_base_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

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

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
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.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

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

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}
Levon Petrosyan
fuente
¿Puede proporcionar un ejemplo de una actividad que use esta actividad base?
CDrosos
Realmente no puedo recordar ningún detalle sobre esto, creo que solo debería funcionar la extensión AppBaseActivity y la setContentViewforma predeterminada.
Levon Petrosyan
6

Para cualquier otra persona que busque hacer lo que le pide el póster original, considere usar fragmentos en lugar de la forma en que Kevin lo dijo. Aquí hay un excelente tutorial sobre cómo hacer eso:

https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer

Si opta por utilizar actividades en lugar de fragmentos, se encontrará con el problema de que el cajón de navegación se vuelva a crear cada vez que navegue a una nueva actividad. Esto da como resultado una representación fea / lenta del cajón de navegación cada vez.

Micro
fuente
5

Mi sugerencia es: no use actividades en absoluto, en su lugar use fragmentos y reemplácelos en el contenedor (diseño lineal, por ejemplo) donde muestra su primer fragmento.

El código está disponible en Tutoriales para desarrolladores de Android, solo tiene que personalizarlo.

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

Es aconsejable que use más y más fragmentos en su aplicación, y solo debe haber cuatro actividades básicas locales para su aplicación, que mencione en su AndroidManifest.xml aparte de las externas (FacebookActivity por ejemplo):

  1. SplashActivity: no usa ningún fragmento y usa el tema de pantalla completa.

  2. LoginSignUpActivity: no requiere NavigationDrawer en absoluto, y tampoco el botón de retroceso, así que simplemente use la barra de herramientas normal, pero al menos, se requerirán 3 o 4 fragmentos. Utiliza el tema sin barra de acción

  3. HomeActivity o DashBoard Activity: utiliza el tema sin barra de acción. Aquí necesita el cajón de navegación, también todas las pantallas que siguen serán fragmentos o fragmentos anidados, hasta la vista de hoja, con el cajón compartido. Todos los ajustes, perfil de usuario, etc. estarán aquí como fragmentos, en esta actividad. Los fragmentos aquí no se agregarán a la pila posterior y se abrirán desde los elementos del menú del cajón. En el caso de fragmentos que requieren el botón de retroceso en lugar del cajón, hay un cuarto tipo de actividad a continuación.

  4. Actividad sin cajón. Esta actividad tiene un botón de retroceso en la parte superior y los fragmentos en el interior compartirán la misma barra de acción. Estos fragmentos se agregarán al back-stack, ya que habrá un historial de navegación.

[Para más información, consulte: https://stackoverflow.com/a/51100507/787399 ]

Feliz codificación !!

Abhinav Saxena
fuente
Esta es una publicación anterior. Puede usar fragmentos para asegurarse de tener siempre una actividad. Sigue reemplazando los fragmentos en un contenedor dedicado a él. Coloque la pila hacia atrás cuando necesite navegación hacia atrás o haga estallar todos los fragmentos cuando necesite que un fragmento se muestre como el primero.
Abhinav Saxena
@ Cabuxa.Mapache Por favor, consulte el enlace adjunto a mi respuesta para obtener más ayuda. He tomado una BaseActivity común, que ayuda a compartir ActionBar ToolBar y NavigatonDrawer y otros componentes en todos los fragmentos adjuntos.
Abhinav Saxena
1

Actualice este código en baseactivity. y no olvide incluir drawer_list_header en su actividad xml.

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.drawer_list_header);

y no use request () en su actividad. pero aún así el cajón no es visible al hacer clic en la imagen ... y al arrastrarlo será visible sin elementos de la lista. Lo intenté mucho pero no tuve éxito. Necesito algunos entrenamientos para esto ...

MS Gadag
fuente
1

Con la respuesta de @Kevin van Mierlo, también es capaz de implementar varios cajones. Por ejemplo, el menú predeterminado ubicado en el lado izquierdo (inicio) y otro menú opcional, ubicado en el lado derecho, que solo se muestra cuando se cargan fragmentos determinados.

He podido hacer eso.

russellhoff
fuente
1
package xxxxxx;



import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.widget.SearchView;
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.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


public class loginhome extends AppCompatActivity {
    private Toolbar toolbar;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

    // Make sure to be using android.support.v7.app.ActionBarDrawerToggle version.
    // The android.support.v4.app.ActionBarDrawerToggle has been deprecated.
    private ActionBarDrawerToggle drawerToggle;

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

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        //Initializing NavigationView


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

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu

            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state
                if(menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()){


                    //Replacing the main content with ContentFragment Which is our Inbox View;
                    case R.id.nav_first_fragment:
                        Toast.makeText(getApplicationContext(),"First fragment",Toast.LENGTH_SHORT).show();
                         FirstFragment fragment = new FirstFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,fragment);
                        fragmentTransaction.commit();
                        return true;

                    // For rest of the options we just show a toast on click
                    case R.id.nav_second_fragment:
                        Toast.makeText(getApplicationContext(),"Second fragment",Toast.LENGTH_SHORT).show();
                        SecondFragment fragment2 = new SecondFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction2.replace(R.id.frame,fragment2);
                        fragmentTransaction2.commit();
                        return true;

                    default:
                        Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                        return true;

                }
            }
        });

        // Initializing Drawer Layout and ActionBarToggle
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close){

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessay or else your hamburger icon wont show up
        actionBarDrawerToggle.syncState();







    }

use esto para su toolbar.xml

<?xml version="1.0" encoding="utf-8"?>

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"


        >

    </android.support.v7.widget.Toolbar>

use esto para el encabezado de navegación si desea usar

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/navhead"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:textColor="#ffffff"
            android:text="tanya"
            android:textSize="14sp"
            android:textStyle="bold"

            />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="tanya.com"
            android:textSize="14sp"
            android:textStyle="normal"

            />
    </LinearLayout>
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_below="@+id/imageView"
        android:layout_marginTop="15dp"

        android:src="@drawable/face"
        android:id="@+id/circleView"
        />



</RelativeLayout>
Volverine
fuente
1

Lo hago en Kotlin así:

open class BaseAppCompatActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

protected lateinit var drawerLayout: DrawerLayout
protected lateinit var navigationView: NavigationView
@Inject
lateinit var loginService: LoginService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("BaseAppCompatActivity", "onCreate()")
    App.getComponent().inject(this)
    drawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout

    val toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)

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

    val toggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)

    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    toggle.isDrawerIndicatorEnabled = true

    val navigationViewHeaderView = navigationView.getHeaderView(0)
    navigationViewHeaderView.login_txt.text = SharedKey.username
}
private inline fun <reified T: Activity> launch():Boolean{
    if(this is T) return closeDrawer()
    val intent = Intent(applicationContext, T::class.java)
    startActivity(intent)
    finish()
    return true
}

private fun closeDrawer(): Boolean {
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    when (id) {
        R.id.action_tasks -> {
            return launch<TasksActivity>()
        }
        R.id.action_contacts -> {
            return launch<ContactActivity>()
        }
        R.id.action_logout -> {
            createExitDialog(loginService, this)
        }
    }
    return false
}
}

Las actividades para el cajón deben heredar esto BaseAppCompatActivity, llamar super.onCreatedespués de configurar el contenido (en realidad, se puede mover a algún método init) y tener elementos correspondientes para los identificadores en su diseño

Pavlus
fuente
Quería probar su solución, pero aparece este error: "Esta actividad ya tiene una barra de acción proporcionada por la decoración de la ventana". Quiero cambiar entre 3 actividades y cada una tiene su propia barra de aplicaciones. Cree que es posible ?
Davoid
Creo que debes mover tu barra de acción a fragmentos en ese caso. En nuestra aplicación, utilizamos el tema NoActionBar y proporcionamos una barra de herramientas para compatibilidad, por lo que recuerdo.
Pavlus
@Pavlus, ¿cómo se vería el código en la segunda actividad? class trackActivity: BaseAppCompatActivity () {?
Craig P
0

Mi respuesta es solo conceptual sin ningún código fuente. Puede ser útil para algunos lectores como yo entender.

Depende de su enfoque inicial de cómo diseña su aplicación. Básicamente hay dos enfoques.

  1. Crea una actividad (actividad base) y todas las demás vistas y pantallas serán fragmentos. Esa actividad base contiene la implementación de los diseños de cajones y coordinadores. En realidad, es mi forma preferida de hacerlo porque tener pequeños fragmentos autocontenidos facilitará y facilitará el desarrollo de aplicaciones.

  2. Si ha comenzado el desarrollo de su aplicación con actividades, una para cada pantalla, probablemente creará una actividad base, y todas las demás actividades se extenderán a partir de ella. La actividad base contendrá el código para la implementación del cajón y del coordinador. Cualquier actividad que requiera la implementación del cajón puede extenderse desde la actividad base.

Personalmente, preferiría evitar usar fragmentos y actividades mezcladas sin ninguna organización. Eso hace que el desarrollo sea más difícil y te atasque eventualmente. Si lo ha hecho, refactorice su código.

Farruh Habibullaev
fuente
-1

Crea un cajón de navegación en tu MainActivity usando un fragmento.
Inicialice el cajón de navegación en MainActivity
ahora en todas las demás actividades que desee usar el mismo cajón de navegación, ponga DrawerLayout como base y fragmente como cajón de navegación. Simplemente configure android: name en su fragmento apuntando a su fragmento de archivo Java. No necesitará inicializar el fragmento en otras actividades.
Puede acceder a Nav Drawer deslizando el dedo en otras actividades como en la aplicación Google Play Store

droidlabel
fuente