Android: NavigationDrawer y ActionBarCompat

Comencé a trabajar con NavigationDrawer usando ActionBarSherlock y conseguí buenos resultados, pero mi compañía que aprueba este Open Source no es probable que llegue en cualquier momento pronto, así que estoy trabajando para cambiar a ActionBarCompat.

ActionBarCompat fue lanzado oficialmente ayer (24 de julio de 2013). ¿Alguien ha conseguido trabajar bien los unos con los otros? Espero poder contestar mi propia pregunta, pero ver si alguien ha conseguido que esto funcione. ¡La carrera está en marcha! Todos los derechos reservados

Lanzamiento de YouTube en ActionBarCompat: https://www.youtube.com/watch?v=6TGgYqfJnyc


ACTUALIZACIÓN (código de trabajo, sí!): He conseguido la aplicación de ejemplo NavigationDrawer de Google convertido para usar ActionBarCompat y está funcionando bien. Puede encontrarlo aquí como referencia o iniciar su proyecto: https://github.com/bcrider/NavigationDrawerActionBarCompat

La versión 2.x se ve aún mejor que la forma en que lo hizo con ActionBarSherlock, pero voy a tener que trabajar con ActionBarCompat mucho más para ver si me gusta más.


NOTA: Soy demasiado nuevo para agregar más de un enlace en un mensaje, etc, así que estoy respondiendo a mi propia pregunta en lugar de editarlo (espero que no sea contra las reglas?). Editará el original una vez permitido.

Manera simple de agregar el cajón de la navegación con ActionBarCompat: Encontré que convertir mi app existente no era tan malo como pensé que iba a ser. Muestra de Google me llevó a creer Fragmentos eran una necesidad, pero que no era el caso … lejos de ella.

Usted puede simplemente envolver sus diseños existentes con el DrawerLayout y conectar el ListView (o cualquier diseño que contenga el ListView para el caso) para la navegación actual. A continuación, añada el código normal a su actividad existente (extender ActionBarActivity) y construya la navegación como si tuviera que hacerlo de todos modos.

A continuación, se muestra un ejemplo de código con el que ajustar el diseño existente:

<?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" > [YOUR EXISTING LAYOUT GOES HERE] <ListView android:id="@+id/left_drawer" android:layout_width="300dp" 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> 

Si quieres empezar con una aplicación de ejemplo que utiliza fragmentos e ir desde allí, he aquí mi repositorio github basado en el código de ejemplo: https://github.com/bcrider/NavigationDrawerActionBarCompat

He convertido mi aplicación de ActionBarSherlock a ActionBarCompat ayer. He tenido algunos problemas, pero nada demasiado serio.

Tengo algunos comentarios:

Para actualizar los temas, sólo necesitaba anular "Sherlock" a "AppCompat". Por ejemplo, en lugar de heredar de @ style / Theme.Sherlock.Light.DarkActionBar, estoy heredando de @ style / Theme.AppCompat.Light.DarkActionBar.

Para los elementos de acción, sólo actualice de esta manera:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yourapp="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/action_search" android:icon="@drawable/ic_action_search" android:title="@string/action_search" yourapp:showAsAction="ifRoom" /> ... </menu> 

Y en el onCreateOptionsMenu, use el MenuItem normal, pero use métodos estáticos de MenuItemCompat para hacer cosas de ActionBar. Por ejemplo: MenuItemCompat.expandActionView (searchMenuItem);

Si utiliza RoboGuice heredando de RoboSherlockActivity, tendrá problemas si lo acaba de copiar y cambiar a ActionBarActivity. Aquí está mi solución:

 public class RoboActionBarActivity extends ActionBarActivity implements RoboContext { protected EventManager eventManager; protected HashMap<Key<?>, Object> scopedObjects = new HashMap<Key<?>, Object>(); @Inject ContentViewListener ignored; // BUG find a better place to put this @Override protected void onCreate(Bundle savedInstanceState) { final RoboInjector injector = RoboGuice.getInjector(this); eventManager = injector.getInstance(EventManager.class); injector.injectMembersWithoutViews(this); super.onCreate(savedInstanceState); eventManager.fire(new OnCreateEvent(savedInstanceState)); } @Override public void setContentView(int layoutResID) { super.setContentView(layoutResID); contentViewChanged(); } @Override public void setContentView(View view) { super.setContentView(view); contentViewChanged(); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { super.setContentView(view, params); contentViewChanged(); } @Override public void addContentView(View view, ViewGroup.LayoutParams params) { super.addContentView(view, params); contentViewChanged(); } private void contentViewChanged() { RoboGuice.getInjector(this).injectViewMembers(this); eventManager.fire(new OnContentChangedEvent()); } @Override protected void onRestart() { super.onRestart(); eventManager.fire(new OnRestartEvent()); } @Override protected void onStart() { super.onStart(); eventManager.fire(new OnStartEvent()); } @Override protected void onResume() { super.onResume(); eventManager.fire(new OnResumeEvent()); } @Override protected void onPause() { super.onPause(); eventManager.fire(new OnPauseEvent()); } @Override protected void onNewIntent( Intent intent ) { super.onNewIntent(intent); eventManager.fire(new OnNewIntentEvent()); } @Override protected void onStop() { try { eventManager.fire(new OnStopEvent()); } finally { super.onStop(); } } @Override protected void onDestroy() { try { eventManager.fire(new OnDestroyEvent()); } finally { try { RoboGuice.destroyInjector(this); } finally { super.onDestroy(); } } } @Override public void onConfigurationChanged(Configuration newConfig) { final Configuration currentConfig = getResources().getConfiguration(); super.onConfigurationChanged(newConfig); eventManager.fire(new OnConfigurationChangedEvent(currentConfig, newConfig)); } @Override public void onContentChanged() { super.onContentChanged(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); eventManager.fire(new OnActivityResultEvent(requestCode, resultCode, data)); } @Override public Map<Key<?>, Object> getScopedObjectMap() { return scopedObjects; } } 

Ahora, inicia ActionMode con supportStartActionMode () e importa el ActionMode del paquete de la biblioteca.

Para usar el SearchView, necesitas hacer algo como esto:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/search" app:actionViewClass="android.support.v7.widget.SearchView" android:icon="@drawable/abc_ic_search" app:showAsAction="always|collapseActionView" android:title="@string/search"/> </menu> @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.search_menu, menu); searchMenuItem = menu.findItem(R.id.search); searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); if (searchView != null) { searchView.setIconifiedByDefault(false); SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() { public boolean onQueryTextChange(String newText) { return true; } public boolean onQueryTextSubmit(String query) { doSomething(query); return true; } }; searchView.setOnQueryTextListener(queryTextListener); } return super.onCreateOptionsMenu(menu); } 

Las otras cosas están trabajando sin ninguna modificación sino con el paquete de las importaciones.

Puede ver más información aquí: http://developer.android.com/guide/topics/ui/actionbar.html .

Las muestras que vienen con el 4.3 sdk parece prometedor, pero voy a crear un proyecto de prueba y tratar de convertir mi propia aplicación a ActionBarCompact y ver si funciona mejor o peor que ActionBarSherlock! Voy a actualizar este post si tengo éxito o no!

Si bien el ejemplo proporcionado es bueno, hice otro ejemplo que está un poco más cerca del ejemplo original de Google Navigation Drawer, ya que incluye todo el código original (ahora con el objetivo de admitir la biblioteca) y el formateo. Sólo algunos atributos tuvieron que ser reemplazados por otros similares, ya que sólo están disponibles a partir de la v11.

Descargar en: https://github.com/GunnarBs/NavigationDrawerWithActionBarCompat

Nota: esto requiere la presencia de la biblioteca v7 appcompat, consulte http://developer.android.com/tools/support-library/setup.html para obtener más información.

  • Cómo agregar iconos a elementos en un cajón de navegación
  • Android: Viewpager dentro de un fragmento del cajón de navegación
  • ¿Cómo puedo borrar la pila de navegación?
  • Android KitKat: android.view.InflateException: Error al inflar la clase android.support.design.widget.NavigationView
  • ¿Hay alguna manera de invocar la navegación desde un navegador móvil?
  • Ocultar permanentemente la barra de navegación en una actividad
  • Cómo agregar funcionalidad de flecha de botón Volver en barra de navegación
  • Android ViewPager Botón Anterior / Siguiente
  • La forma correcta de manejar la navegación "Up" de acuerdo con las directrices
  • Desactivación de los botones de navegación de Android para niños discapacitados
  • Menú de navegación lateral como la aplicación de Facebook
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.