Sliding Menu en Android

Hace tiempo que tenía ganas de ver como funcionaban los menús laterales estilo Facebook o Google+. Por suerte hace poco he podido utilizarlos en un proyecto y está dando un buen resultado. Gracias a las librerías existentes implementarlo en un proyecto se vuelve un juego de niños.


Lo primero de todo será buscar una librería, yo encontré varias y me decanté por esta la de jfeistein10 en GitHub.com https://github.com/jfeinstein10/SlidingMenu podéis seguirlo a través de Twitter @SlidingMenu además de otras redes sociales y dispone de una aplicación en el market de Google por si quereis ver todos los ejemplos de su librería. Aquí tenéis una captura de pantalla.




Empezamos descargando su librería en el anterior enlace y la descomprimimos. Yo suelo hacerlo en una carpeta donde guardo todas las librerías de Android que voy utilizando. Ahora vamos a Eclipse y crearemos un proyecto nuevo. Indicamos que es un proyecto sobre código existente. Buscamos la carpeta que descomprimimos, y dentro de esta seleccionamos library  y aceptamos.

En el nuevo proyecto hacemos botón derecho sobre él y seleccionamos Properties > Android. En mi caso se construye sobre la versión 2.1 de Android. Debemos cambiarlo a la versión 4.0.3 con las librerías de Google Maps. Después de esto veremos que hay unos layouts que dan error, concretamente en el layout_width y layout_height por la propiedad match_parent, la cambiamos por fill_parent, guardamos y volvemos a poner match_parent y volvemos a guardar. No se porque pasa esto, puede ser que no le de tiempo a evaluar correctamente el proyecto con la nueva versión, pero es algo que ya me ha pasado en 3 ordenadores diferentes.

Si estáis en el caso que utilizáis la librería ActionBarSherlock como es mi caso, debéis hacer un cambio más. Otra vez haceis botón derecho sobre el proyecto del SlidingMenu, Properties > Android. En la sección Library añadis una librería y seleccionáis donde tengais la ActionBarSherlock.

Ahora debeis abrir todas las clases que hacen referencia a una Activity en este proyecto, terminan todas por Activity, y el cambio es muy fácil, simplemente hay que cambiar la herencia por la correspondiente clase de la ActionBarSherlock. Por ejemplo, extends Activity quedaría extends SherlockActivity. Por supuesto, si no utilizais la ActionBarSherlock, estos dos pasos no son necesarios.

Además si teneis la librería ActionBarSherlock debeis quitar de la SlidingMenu la librería android-support-v4 porque de lo contrario os dará un error diciendo que está repetida.

Ya tenemos lista la librería para utilizar en nuestro proyecto. Seguimos los mismos pasos que seguimos para añadir la librería ActionBarSherlock antes pero ahora en nuestro proyecto y añadiendo la librería del SlidingMenu.

Antes de llamar al SlidingMenu en nuestra activity vamos a crear una serie de archivos necesarios. El primero se llama shadow.xml y se ubica en drawable. Es una sombra que se utilizará en el menú.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <gradient
        android:endColor="#33000000"
        android:centerColor="#11000000"
        android:startColor="#00000000" />
</shape>


El siguiente es dimens.xml y se ubica en values. Sirve para guardar tamaños o dimensiones de objetos y se pueden utilizar de una forma muy similar a como lo hacemos en styles o strings.xml.


<resources>
    <dimen name="slidingmenu_offset">60dp</dimen>
    <dimen name="list_padding">10dp</dimen>
    <dimen name="shadow_width">15dp</dimen>
    <integer name="num_cols">1</integer>
</resources>



Ahora vamos a la carpeta layout y creamos menu_list.xml, este archivo mostrará la lista de opciones de nuestro menú en un ListView. Es un layout normal que se utiliza de la misma forma que en cualquier activity.


<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="5dip"
    android:paddingRight="5dip" />


Seguimos en la carpeta layout y creamos menu_row.xml, será la plantilla utilizada para cada uno de los items de nuestro ListView anterior.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/row_icon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:padding="10dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/row_title"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:padding="10dp"
        android:text="Medium Text"
        android:textAppearance="@android:style/TextAppearance.Medium" />
</LinearLayout>



El último de los archivos de la carpeta layout será menu.xml, este es el layout que deberá llamar nuestro SlidingMenu. En el atributo android:name estamos poniendo el espacio de nombres de nuestra aplicación seguido de la clase MenuFragment que explicaremos ahora. A este fragment le estamos diciendo que cuando se empiece a utiliza esta vista debe llamar a la clase MenuFragment.


<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="aqui.vuestro.espacio.de.nombres.MenuFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</fragment>


La siguiente clase se llama MenuFragment y hereda de ListFragment. Lo que hará esta clase es al crear la vista en el onCreateView decirle que debe utilizar el layout menu_list.xml. Cuando la Activity se crea inicializamos la clase SampleAdapter que no es más que una clase auxiliar que hereda de ArrayAdapter y que nos ayudará a añadir cada uno de los items al ListView.


Podríamos en vez de tener un ListView utilizar cualquier otro elemento como  un ScrollView con diferentes elementos anidados o lo que se os ocurra o necesiteis. Se accede de la misma forma a los elementos como si lo hicieramos en una Activity normal.


public class MenuFragment extends ListFragment {

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  return inflater.inflate(R.layout.menu_list, null);
 }

 public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  SampleAdapter adapter = new SampleAdapter(getActivity());
  for (int i = 0; i < 20; i++) {
   adapter.add(new SampleItem("Sample List", android.R.drawable.ic_menu_search));
  }
  setListAdapter(adapter);
 }

 private class SampleItem {
  public String tag;
  public int iconRes;
  public SampleItem(String tag, int iconRes) {
   this.tag = tag; 
   this.iconRes = iconRes;
  }
 }

 public class SampleAdapter extends ArrayAdapter<SampleItem> {

  public SampleAdapter(Context context) {
   super(context, 0);
  }

  public View getView(int position, View convertView, ViewGroup parent) {
   if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.menu_row, null);
   }
   ImageView icon = (ImageView) convertView.findViewById(R.id.row_icon);
   icon.setImageResource(getItem(position).iconRes);
   TextView title = (TextView) convertView.findViewById(R.id.row_title);
   title.setText(getItem(position).tag);

   return convertView;
  }

 }
 
}

Por último vamos a ver como añadir el SlidingMenu a nuestra Activity. Para ello abrimos la Activity donde lo utilizaremos. Lo primero de todo es cambiar la herencia por una de las Activitys que modificamos antes en la librería SlidingMenu. En este caso por SlidingFragmentActivity, esto nos proporcionará los métodos necesarios para añadir el menú lateral.


Lo siguiente es indicar cual es el layout de nuestro menú de una forma a como lo haríamos con setContentView pero con setBehindContentView. Y ahora inicializamos y seteamos nuestro SlidingMenu. Le indicamos el modo en como debemos tocar la pantalla para deslizar, el ancho de la sombra del menú, el drawable... Hay bastantes opciones de configuración y os recomiendo que le echeis un vistazo a la aplicación que hay disponible con los ejemplos y al código disponible en github.


Después de configurar todo habilitamos la action bar y el botón de home para poder tocar en este y abrir y cerrar el menú. Por último, capturamos el evento correspondiente a cuando pulsamos un item del menú (en este caso el menú de siempre de Android) y evaluamos si es el botón de home de la action bar, en caso de serlo hacemos un toggle que será el método encargado de abrir o cerrar el SlidingMenu según corresponda.


public class MiActivity extends SlidingFragmentActivity{ 
 
 private SlidingMenu menu;
 
 
  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        setBehindContentView(R.layout.menu);
        
        setSlidingActionBarEnabled(false);        

        menu = new SlidingMenu(this);
        menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        menu.setShadowWidthRes(R.dimen.shadow_width);
        menu.setShadowDrawable(R.drawable.shadow);
        menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
        menu.setFadeDegree(0.35f);
        menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        
        getSupportActionBar().setDisplayShowCustomEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);        
        
  }

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
        case android.R.id.home:     
         toggle();           
            return true;               
        default:
            return super.onOptionsItemSelected(item);
        }  
    }
}




Comments are closed.