Múltiples actividades (no fragmentos) con un NavigationDrawer. ¿Cómo mostrar la actividad seleccionada actualmente?

Tenía una aplicación con bastantes actividades antes de que se decidiera que usaríamos un cajón de la navegación o un menú de la hamburguesa. No quería rehacer la aplicación entera utilizando fragmentos, así que decidí ir con el enfoque utilizado en esta respuesta: mismo cajón de navegación en diferentes actividades

EDIT: Y ahora, esta https://stackoverflow.com/a/23477100/1371585

Y creé una actividad básica llamada NavDrawerBaseActivity . Aquí está el código:

  public class NavDrawerBaseActivity extends MyBaseActivity { public DrawerLayout mNavDrawerLayout; public ListView mDrawerList; public String[] mMenuItems; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.navdrawer_activity); mNavDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mMenuItems = getResources().getStringArray(R.array.optionsmenu_array); mDrawerList = (ListView) findViewById(R.id.left_drawer); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, mMenuItems); mDrawerList.setAdapter(adapter); mDrawerList.setOnItemClickListener(new DrawerItemClickListener(this)); super.onCreate(savedInstanceState); } private class DrawerItemClickListener implements ListView.OnItemClickListener { private DrawerItemClickListener(Context context) { mContext = context; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String textClicked = ((TextView) view).getText().toString(); view.setSelected(true); if (textClicked.equalsIgnoreCase(mContext .getString(R.string.optionsmenu_library))) { Intent libraryIntent = new Intent(mContext, LibraryActivity.class); libraryIntent.putExtra("navdrawerposition", position); startActivity(libraryIntent); mNavDrawerLayout.closeDrawers(); mDrawerList.setItemChecked(position, true); //Not working } else if (textClicked.equalsIgnoreCase(mContext .getString(R.string.optionsmenu_settings))) { // TODO: open activity and close the drawer } else if (textClicked.equalsIgnoreCase(mContext .getString(R.string.optionsmenu_logout))) { // TODO: open activity and close the drawer } } private Context mContext; } } 

Aquí está el archivo de diseño navdrawer_activity.xml

  <?xml version="1.0" encoding="utf-8"?> <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" > <FrameLayout android:id="@+id/activity_frame" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#111" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" /> </android.support.v4.widget.DrawerLayout> 

Cada actividad amplía la NavDrawerBaseActivity y no utiliza setContentView , así:

  public class LibraryActivity extends NavDrawerBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Not setting content view here, since its already set in // NavDrawerBaseActivity FrameLayout frameLayout = (FrameLayout) findViewById(R.id.activity_frame); // Inflating the Camera activity layout LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View activityView = layoutInflater .inflate(R.layout.library_page, null, false); // Adding the custom layout of this activity to frame layout set in // NavDrawerBaseActivity. frameLayout.addView(activityView); // Only this part of the code is doing what I want. // int drawerSelectedPosition = getIntent().getIntExtra(mNavDrawerPosExtraName, -1); // if(drawerSelectedPosition > -1){ // mDrawerList.setItemChecked(drawerSelectedPosition, true); // } } } 

Mi problema: ¿Cómo puedo resaltar correctamente la actividad actual en la vista de NavDrawer? El mDrawerList.setItemChecked(position, true); Antes de lanzar Intent o después de lanzarlo no está funcionando.

La parte extraña es: Si estoy actualmente en Activity1, abra el NavDrawer y seleccione Activity2. Desembarco en Activity2, abra el NavDrawer y ver que "Activity2" no está seleccionado. Hago clic en el botón Atrás, aterrizar en Actividad1, abrir el NavDrawer y ver que "Actividad2" está seleccionado.

Lo que significa que setItemChecked funciona, pero no en la nueva actividad que se setItemChecked .

Actualmente estoy pasando la posición como un intento adicional y específicamente la configuración de la posición de verificación, como la sección comentada en LibraryActivity . Esto funciona pero parece un trabajo alrededor. Por favor dígame si hay una manera correcta / mejor de hacer eso en la clase de NavDrawerBaseActivity en vez de en cada actividad que lo extiende.

No ponga un cajón de nav en cada actividad, esto derrota el propósito de extender la clase de NavDrawerBaseActivity. Debido a que todas sus otras actividades amplían esta clase base deben heredar automáticamente toda su funcionalidad. Por lo tanto, sólo ponga el cajón en la NavDrawerBaseActivity. Entonces, en su xml para el cajón usted puede especificar cada acción de los botones como:

 <Button style="@style/drawerBtn" android:id="@+id/activity1Btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick"> 

O simplemente establecer un oyente onClick en su cajón, algo así como:

 myDrawer.setOnClickListener().........etc 

A continuación, en su controlador onClick (que se encuentra dentro de la clase NavDrawerBaseActivity), puede simplemente comprobar qué botón se pulsó y abrir la actividad asociada, algo así como:

 //remember, if you used the onClickListener you have to use @Override at the top of this function public void onClick(View item) { //lets see which button on the drawer was pressed....item is the item that triggered the click switch (item.getId()) { case R.id.activity1Btn: Intent intent1 = new Intent(this, Activity1.class); startActivity(intent1); break; case R.id.activity2Btn: Intent intent2 = new Intent(this, Activity2.class); startActivity(intent2); break; case R.id.activity3Btn: Intent intent3 = new Intent(this, Activity3.class); startActivity(intent3); break; } } 

Recuerde que Actividad1, Actividad2, Actividad3 tendrán que extender NavDrawerBaseActivity, que entonces tiene que extender Actividad o extender otra clase que a su vez extiende Actividad …… y así sucesivamente y así sucesivamente. También puede establecer cosas como mDrawerList.setItemChecked (position, true) en este modificador . Por lo tanto, en resumen, hacer que todas las cosas de cajón sucedan en esta clase sólo y simplemente "implementar" esta clase mediante la extensión, recuerde que esta clase contiene toda la funcionalidad que es común en todas las clases / actividades "infantiles", todos heredan este comportamiento

EDITAR:

Si desea resaltar los elementos de su cajón y debe utilizar setSelected (true) en su elemento. Puede definir estados de selección personalizados si desea creando un estilo de selección en su carpeta drawables. A continuación, establezca este estilo como el fondo de su ejemplo de elementos de lista:

 <!-- drawable/myStyles.xml--> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:state_pressed="true" android:drawable="@color/blue"/> <!--item selected state--> <item android:state_enabled="true" android:state_focused="true" android:drawable="@color/blue"/> <!--item selected state--> <item android:state_enabled="true" android:state_selected="true" android:drawable="@color/blue"/> <!--item selected state--> <item android:state_focused="false" android:state_pressed="false" android:drawable="@color/gray"/> <!--item NOT selected state--> </selector> 

Y su artículo del cajón:

 <LinearLayout android:id="@+id/my_drawer_item" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="fill_parent" android:background="@drawable/myStyles"> 

A continuación, en la instrucción switch / if-else, se establece el elemento seleccionado como myNewSelectedView.setSelected (true) . Es posible que deba anular la selección manualmente del antiguo como myOldSelectedItem.setSelected (false)

A continuación, haga clic en / select listener donde tiene que cambiar / if-else instrucción:

  @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { view.setSelected(true) //....the rest of your code here } 

Por último te recomiendo que pruebes esto primero ya que esta será la ruta más fácil de seguir si usas una lista normal.

 <ListView android:id="@+id/my_list" android:choiceMode="singleChoice" android:listSelector="@android:color/blue" /> 

EDIT2:

Ahora para retener el estado de los elementos seleccionados … Así que parece que cada acción en el cajón reinstantiates la clase base que no es ideal. Necesitamos retener de alguna manera el estado de la instancia para que actúe casi como un singleton. He intentado sobreescribir el onSaveInstanceState y usar el estado singleInstance launcher, pero no funcionó. Por lo tanto, para el interino he llegado con la solución de guardar la selección actual en la memoria como una variable estática:

 private static int mCurrentSelectionIndex = 0; //this is defined at the top of your class with your default selected screen ie the first item in the list. //then in setContentView after assigning the drawer layout you set the currentSelection @Override public void setContentView(final int layoutResID) { //...... first assign the layouts ie mDrawerList = findViewByLayout(R.id.myDrawerList) etc mDrawerList.setSelection(mCurrentSelectionIndex); // OR: mDrawerList.setItemChecked(mCurrentSelectionIndex, true); } //then in onClick() public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mCurrentSelection = position; item.setSelected(true); } 
  • Android cambia el ancho del panel del cajón de navegación mediante programación
  • DrawerLayout se debe medir con MeasureSpec.EXACTLY error
  • LinearLayout $ LayoutParams no se puede convertir en android.support.v4.widget.DrawerLayout $ LayoutParams
  • No muestre la superposición con el Cajón de navegación de Android
  • Determinar si el NavigationDrawer está abriendo o cerrando
  • Cómo cerrar el cajón de navegación cuando se pulsa un elemento desde el mismo?
  • BaseActivity para la navegación
  • Cómo crear un cajón de navegación suave
  • Android - ¿Es posible cajón de navegación desde el lado derecho?
  • Elemento seleccionado en el cajón de navegación
  • Icono de Android ic_drawer.png en color blanco?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.