Mismo cajón de navegación en diferentes actividades

Hice un cajón de navegación de trabajo como se muestra en el tutorial en el sitio web developer.android.com . Pero ahora, quiero usar un cajón de navegación, que he creado en la clase 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 este cajón de navegación Android de respuesta 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 deseo tener el cajón de la navegación así que extiendo el 'NavigationDrawer' y en algunas otras actividades que deseo al usuario el mismo cajón de la navegación

  public class SampleActivity extends NavigationDrawer {...} 

No sé qué cambiar …

Si desea un cajón de navegación, debe utilizar fragmentos. He seguido este tutorial la semana pasada y funciona muy bien:

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

También puede descargar código de ejemplo de este tutorial, para ver cómo puede hacerlo.


Sin fragmentos:

Este es su código de BaseActivity:

 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 otras Actividades que necesitan tener un cajón de navegación deben extender esta Actividad en lugar de la Actividad misma, 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:

He experimentado algunas dificultades a mí mismo, por lo que aquí es una solución si obtiene 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 arreglar 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.


Editar 2:

Como dijo @GregDan su BaseAcivity también puede anular setContentView() y llamar a onCreateDrawer allí:

 @Override public void setContentView(@LayoutRes int layoutResID) { super.setContentView(layoutResID); onCreateDrawer() } 

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

Utilizan 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 asegura que se trata de un uso correcto del patrón de cajón de navegación. Cada actividad tiene opcionalmente un DrawerLayout como su disposición principal. La parte interesante es cómo se hace la navegación a otras pantallas. Se implementa en BaseActivity como esto:

 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 manera común de reemplazar el fragmento actual por una transacción de fragmentos. Pero el usuario no detecta una diferencia visual.

Hay un trabajo alrededor: En mi ejecución: Tengo fragmentos en la primera actividad que tiene cajón de la navegación. Las otras actividades crean el ActionBar y el Cajón de Navegación del mismo código que la primera actividad, y no tienen fragmentos, la disposición se describe más adelante aquí. En la primera actividad, el clic de acción del elemento se maneja en la misma actividad, y en las otras actividades, la acción se completa más tarde, primero conmuto a la primera actividad, cerrando las otras actividades. Las condiciones son las siguientes:

  1. He puesto el diseño principal y el primer framelayout del interior, y el segundo framelayout se dedica al cajón en DrawerLayout.

  2. He hecho la inicialización del cajón en el resto de las actividades distintas de la primera. Esto es porque necesita reinicializarse después de actualizaciones de nuevas intenciones, ya que todas las actividades son de instancia única.

De esta manera he podido tener NavigationDrawer y ActionBarCompat en todas las actividades.

Para cualquier persona que quiera hacer lo que el cartel original está pidiendo, por favor considere utilizar fragmentos en lugar de la manera en que Kevin dijo. Aquí hay un excelente tutorial sobre cómo hacer eso:

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

Si elige utilizar actividades en lugar de fragmentos, se va a ejecutar en el problema de que el cajón de navegación se vuelve a crear cada vez que navega a una nueva actividad. Esto da lugar a una representación fea / lenta del cajón de la nave cada vez.

Actualizar este código en baseactividad. Y no te olvides de incluir drawer_list_header en tu 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. Intenté mucho pero no tuve éxito. Necesito algunos entrenamientos para esto …

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

He podido hacer eso.

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

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

Utilice esto para el encabezado de navegación si desea utilizar

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

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 esta BaseAppCompatActivity , llamar a super.onCreate después de que el contenido esté configurado (en realidad, se puede mover a algún método init) y tener los elementos correspondientes para los ids en su diseño

Cree un cajón de navegación en su fragmento MainActivity.
Inicialice el cajón de navegación en MainActivity
Ahora en todas las demás actividades que desea utilizar el mismo cajón de navegación poner DrawerLayout como base y fragmento como el cajón de navegación. Simplemente establezca android: nombre en su fragmento apuntando a su fragmento de archivo Java. No necesitará inicializar el fragmento en otras actividades.
Puede acceder al Nav Drawer mediante desplazamientos en otras actividades como en la aplicación Google Play Store

  • Android NavigationView con espaciado interno
  • Restauración del estado del fragmento al cambiar fragmentos a través de la barra de navegación inferior
  • Cómo configurar varias actividades de los padres para usar el botón de retroceso de Android
  • Mejores prácticas de Android para conectar las actividades
  • Barra de navegación ligera Android
  • Administrar correctamente la navegación Tabbar con ActivityGroup o Fragments etc en Android?
  • Menú de navegación lateral como la aplicación de Facebook
  • Línea azul claro sobre mi barra de navegación en la aplicación de Android
  • Android lollipop toolbar conmutador entre abrir / cerrar el cajón y el botón Atrás
  • ¿Cómo comprobar si google.navigation intent / url scheme es compatible desde dentro de una aplicación web?
  • ¿Cómo extender la vista de la disposición del cajón?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.