Patrón de diseño: Navigation Drawer
jueves, mayo 23, 2013 at 8:57AM
jtristan in Navigation drawer, Tutorial Android

Aunque este patrón está presente desde hace mucho tiempo en muchas aplicaciones Android e incluso en las propias de Google, hasta ahora, era necesario utilizar librerías de terceras partes para poderle implementar. El problema con el uso de estas diferentes librerías, es que cada una aportaba una funcionalidad y aspecto diferente.

Ahora, ya es posible, encontrarnos con el patrón en las guías de diseño además de haber liberado una actualización en su librería de soporte, de forma, que todos los desarrolladores puedan utilizar este patrón de la misma forma.



El action bar, se ha usado para temas de navegación, ahora ya con el nuevo patrón,  tenemos que tener en cuenta que el action bar sólo es para las acciones y el navigation drawer para la navegación.

¿Qué es el Navigation Drawer?

Seguro que lo habéis visto en muchas aplicaciones. Es un panel que se desplaza desde el borde de la  parte derecha y que visualiza las principales opciones de navigación de la aplicación. Cuando desplazamos el navigation drawer, le superponemos sobre el contenido de la pantalla, pero no sobre el action bar. Sin embargo, el action bar modifica su contenido, pues elimina todas las opciones que tuviese la vista y las sobreescribe por el icono y el nombre de la aplicación. Sólo se mantiene el menú de desbordamiento con los elementos para las accione estandar para la parametrización y la ayuda.



Para ocultar el menú, el usuario tiene cuatro opcioes:

El Navigation drawer puede contener títulos. Estos no son interactivos, sólo nos valdrán para organizar los objetivos de navegación en temas.

También podemos añadir a cada objetivo iconos y contadores. Los contadores sirven para informar al usuario cambios en el estado de los datos en la correspondiente vista.

Dentro del Navigation drawer también podemos plegar diferentes elementos que están subordinados a un elemento principal.



Finalmente, unos consejos acerca del estilo. El ancho, naturalmente dependerá del contenido a visualizar, pero como mínimo siempre tendrá 240 dp y un máximo de 320 dp. La altura de cada elemento no deberá superar los 48 dp.

Ejemplo.

Lo primero que haremos será envolver todo el contenido del layout con un DrawerLayout (android.support.v4.widget.DrawerLayout) y añadir un ListView que va a ser el que contenga la lista de navegación.

 

    
  
    
    
    

Hay que tener en cuenta que:


El siguiente paso es adjuntar el adaptador a la ListView para inicializar la lista de elemento del navigation drawer.
Vamos a utilizar un ArrayAdapter al que le pasamos un array de Strings que recuperamos de los recursos. Además, necesitamos registrar un callback para poder resonder a la selección de las opciones de navegación.

String[]posicionesDrawer;
	DrawerLayout dwLayout;
	ListView lvDrawer;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.activity_main);
	    
	    posicionesDrawer = getResources().getStringArray(R.array.opciones);
	    
	    lvDrawer = (ListView) findViewById(R.id.lvDrawer);
            dwLayout = (DrawerLayout) findViewById(R.id.dwlayout);
	    
	    ArrayAdapter adaptador = new ArrayAdapter(this,	            										android.R.layout.simple_list_item_1, 
       		posicionesDrawer);
	    lvDrawer.setAdapter(adaptador);
	    lvDrawer.setOnItemClickListener(this);
	 
	 	}

Cuando recibimos la pulsación de la opción, llamamos al fragmento que queremos cargar.

@Override
	public void onItemClick(AdapterView padre, View vista, int posicion, long id) {
		
		seleccionarPosicion(posicion);
		
	}
	
	private void seleccionarPosicion(int posicion) {
	    
	    Fragment fragment = new PosicionFragment();
	    Bundle args = new Bundle();
	    args.putInt(PosicionFragment.NUMERO_POSICION, posicion);
	    fragment.setArguments(args);

	    android.app.FragmentManager fragmentManager = getFragmentManager();
	    fragmentManager.beginTransaction()
	    			   .replace(R.id.main_frame, fragment)	                   
	                   .commit();
	    
	    lvDrawer.setItemChecked(posicion, true);
	    setTitle(posicionesDrawer[posicion]);
	    dwLayout.closeDrawer(lvDrawer);
	}

	@Override
	public void setTitle(CharSequence titulo) {		
	    getActionBar().setTitle(titulo);
	}
	
	
	
	
		
    public static class PosicionFragment extends Fragment {
        public static final String NUMERO_POSICION = "numero_posicion";

        public PosicionFragment() {

        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
        	
            View rootView = inflater.inflate(R.layout.fragmento, container, false);
            int i = getArguments().getInt(NUMERO_POSICION);            
            
            String texto = getResources().getStringArray(R.array.textos_fragmentos)[i];
            ((TextView) rootView.findViewById(R.id.tvFragmento)).setText(texto);
            getActivity().setTitle(texto);
            return rootView;
        }
    }

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.