domingo, 15 de junio de 2014

Menú lateral desplegable DrawerLayout android (Slider)

Buenos días!

Hoy vamos a ver como crear un menú desplegable del tipo Google Maps o google plus +.  Parece algo complicado pero he intentado hacerlo lo más simple posible! eso si, siempre se puede perfeccionar muchísimo subiendo así el nivel de dificultad.
Para que funcione el nivel desplegable es necesario API 11 y si queremos desplearlo con un botón en vez de arrastrando con el dedo ará falta la versión API 14.





Como siempre he creado el código totalmente comentado. Para empezar mostraré el Xml, basado en  android.support.v4.widget.DrawerLayout, simplemente he añadido un listview.
<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/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
    <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="#ff11"/>
</android.support.v4.widget.DrawerLayout>
Una vez visto el Xml a continuación el Java:
package com.tywors.menulateral.app;

import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {
    //El drawerLayout esn el que se desplega y
    //contiene dentro el menú, normalmente un listview
    private DrawerLayout mDrawerLayout;
    //Declaremos el ListView
    private ListView mDrawerList;
    //ActionBarDrawerToggle es donde aparecerá el boton
    //para desplegar el menú
    private ActionBarDrawerToggle mDrawerToggle;

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

        //relacionamos ocn el XML
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);
        //Configuramos el Boton que desplegará el menú
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                 //la actividad
                mDrawerLayout,         //el drawerLayout que desplegará
                R.drawable.ic_launcher, //el icono que mostraremos
                R.string.app_name,  //descripción al abrir
                R.string.app_name  //descripción al cerrar
        ) {     };

        //Creamos nuestro menú
        final String[] opciones = {"Inicio", "Descargas", "Salir"};
        //rellenamos la List view
        mDrawerList.setAdapter(new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1,
                android.R.id.text1, opciones));

        //Añadimos la acción que haga en cada fila del
        //list view. en este caso solo mostraremos un Toast con un mensaje
        mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, 
                                    int arg2, long arg3) {
                Toast.makeText(MainActivity.this, "id: " + opciones[arg2],
                        Toast.LENGTH_SHORT).show();
                //Se cierra el menú
                mDrawerLayout.closeDrawers();
            }
        });

        //Mostramos el botón en la barra de la aplicación
        getActionBar().setDisplayHomeAsUpEnabled(true);
        //Activamso el click en el icono de la aplicación
        getActionBar().setHomeButtonEnabled(true);

    }

    //Que el botón de desplegar siempre este sincronizado
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }
    //Igual con la configuración
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
    //Activamos el click paradesplegar
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
Espero vuestros comentarios!!!
Muchas Gracias!!!

11 comentarios:

  1. Hola, gracias por tu aporte ... soy novato en este tema y tengo dos preguntas, espero me puedas ayudar .....

    1)Al XML le agresgaste solamente un ListView, yo ya tengo mi activity principal que hereda de "ActionBarActivity" que parte de un "LinearLayout", quiero entender que para mi caso, el archivo XML en lugar de contener el ListView, contendrá el "LinearLayOut?
    2) El DrawerLayout, solo se agrega por código? no existe ese objeto en la interfaz grafica de ADT asì como aparecen LinearLayout y otros?

    ResponderEliminar
    Respuestas
    1. Son dudas razonables, abra que probar. Yo voy a empezar una app donde utilizaré un menú así.
      En cuanto tenga todo eso resuelto te comentaré el resultado aver.

      Eliminar
  2. q tal, yo lo he implementado pero no logro q los elementos fuera del drawer layout, por ejemplo un boton sea accesible . Y viceversa al hacer accesibles elementos de un layout diferente, el drawer layout no es accesible. Despues de varios intentos hice ambas partes accesibles con fragments pero la cosa es q se encimaban el drawer y los elementos de mi aplicacion... finalmente decidi hacer q todo el contenido de mi app se desplegara junto con el drawer layout, pero creo q no es la idea. Me gustaria saber como poner accesibles tanto el drawer layout como los componentes de mi app, tales como botones, edit view etc... Gracias :) espero haberme explicado un poco :D

    ResponderEliminar
    Respuestas
    1. Si, creo que te he entendido, por lo que parece la integración no se ve muy clara en este tutorial. Intentaré hacer un tutorial en breve donde pondré de ejemplo 2 o 3 layouts y sus interacciones. Muchas gracias por comentar.

      Eliminar
  3. Pésima explicación... no funciona....

    ResponderEliminar
    Respuestas
    1. Funcionar, funciona. Pero si no te bajas las Support Library dudo que te haga nada.

      Eliminar
  4. Como puedo hacer para que con el botón que dice salir se cierre la aplicación ??

    ResponderEliminar
    Respuestas
    1. Añadir OnClickListener y dentro dispose();

      Eliminar
  5. En el IDE de Android Studio hay una plantilla de creacion de proyectos que implementa un menu lateral con fragmentos

    ResponderEliminar
  6. Estaría muy bien que explicaras la implementación porque no consigo hacer que me funcione, sobretodo porque los ActionBar eclipse me dice que ya son deprecated

    ResponderEliminar