Académique Documents
Professionnel Documents
Culture Documents
En Android
noviembre 23, 2014 James Revelo
Este artculo te explicar el uso del Navigation Drawer en Android para crear una
navegacin a travs de un Men deslizante.
Vers como implementar un Drawer Layout para el diseo. Aprenders a manejar los
eventos relacionados. Y tambin a complementar su funcionamiento con la action bar
mediante un Action Bar Drawer Toggle.
Antes de iniciar quiero que veas la aplicacin que podrs construir, una vez hayas
aprendido todas las lecciones de este tutorial:
Descargar Cdigo
Apyanos con una seal en tu red social favorita y consigue el cdigo completo.
Me gusta
Tweet
+1 Google
Como ves, este componente es una de las tantas formas de navegacin en una aplicacin
Android. La gran ventaja de utilizarlo es la expansin de funcionalidades que brinda sin
tener que cambiar entre actividades.
Ejemplo de Navigation Drawer en Android
La aplicacin que construiremos le llamaremos GeekyWeb. Esta es un excelente ejemplo
para implementar un Navigation Drawer que brinde al usuario accesibilidad hacia las
categoras principales de los artculos en un blog sobre Desarrollo Web.
Categoras como: HTML, CSS, Javascript, Angular JS, Python y Ruby on Rails.
Cada vez que el usuario seleccione una categora desde el Navigation Drawer, el layout
principal se actualizar para proyectar su respectivo contenido.
dependencies {
compile 'com.android.support:support-v4:19.1.0'
}
Esta instruccin le indica a gradle que necesitas incluir como dependencia externa la
librera de soporte v4, con una compatibilidad objetivo del SDK 19. Segn la versin que
vayas a compilar pues as mismo puedes especificar el nmero y cambiarla.
Crear un DrawerLayout
Un DrawerLayout es un contenedor especial de la librera de soporte, que alberga dos tipos
de contenido, el contenido principal y el contenido para el Navigation Drawer.
<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">
<RelativeLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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="#111"/>
</android.support.v4.widget.DrawerLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="10dp">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff"
android:text="Item"
android:layout_toRightOf="@+id/icon"
android:layout_centerVertical="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/icon"
android:layout_alignParentLeft="true"
android:layout_marginRight="16dp"
android:layout_centerVertical="true" />
</RelativeLayout>
Ahora solo queda implementar el adaptador usando como tipo de entrada los elementos de
la clase DrawerItem:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
LayoutInflater inflater = (LayoutInflater)parent.getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_list_item, null);
}
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
TextView name = (TextView) convertView.findViewById(R.id.name);
return convertView;
}
}
Como ves, el texto de cada item de la lista fue obtenido desde un array de strings llamado
Tags, el cual est definido de la siguiente forma en strings.xml:
<string-array name="Tags">
<item>HTML</item>
<item>CSS</item>
<item>JavaScript</item>
<item>Angular JS</item>
<item>Python</item>
<item>Ruby</item>
</string-array>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/headlines"
android:id="@+id/headline"
android:layout_centerHorizontal="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_centerHorizontal="true"
android:layout_below="@+id/headline"
android:src="@drawable/article" />
</RelativeLayout>
public ArticleFragment() {
// Constructor vaco obligatorio
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_article, container, false);
int i = getArguments().getInt(ARG_ARTICLES_NUMBER);
String article = getResources().getStringArray(R.array.Tags)[i];
getActivity().setTitle(article);
TextView headline = (TextView)rootView.findViewById(R.id.headline);
headline.append(" "+article);
return rootView;
}
}
Cuando un ArticleFragment es creado se cambiar inmediatamente el titulo de la actividad
por una cadena del array de strings. Para saber que cadena es, se obtiene el argumento
enviado desde la actividad principal (ARG_ARTICLES_NUMBER), que representa la
posicin del item en la lista.
Luego se concatena el texto por defecto que tiene el TextView del fragmento ms el
nombre de la categora.
GeekyWeb tiene una sola clase para todos los fragmentos, ya que cumplen con el mismo
patrn, pero tal vez en tu caso no sea de esta forma. Crea distintos fragmentos
personalizados si cada opcin muestra un contenido con estructura particular.
Veamos:
//Reemplazar contenido
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// Se actualiza el item seleccionado y el ttulo, despus de cerrar el drawer
drawerList.setItemChecked(position, true);
setTitle(tagTitles[position]);
drawerLayout.closeDrawer(drawerList);
}
El mtodo selectItem() recibe como parmetro la posicin del item seleccionado, el cual
debes enviar como argumento con la constante definida en ArticleFragment. Luego de
reemplazar el fragmento en el contenido principal, pasamos a iluminar el item de la lista
(setItemChecked()), cambiar el ttulo de la action bar (setTitle()) y luego cerrar el
drawer(closeDrawer()).
Luego setea una instancia de esta escucha en la lista del Navigation Drawer:
drawerList.setOnItemClickListener(new DrawerItemClickListener());
Y por ultimo dos strings de accesibilidad que contienen la informacin sobre la apertura y
cierre del Drawer.
Sabiendo esta informacin podemos implementar nuestros eventos de apertura y cierre del
Navigation Drawer. La idea es cambiar al titulo de la aplicacin cuando el drawer se abra.
Pero cuando est cerrado se cambiar por el ttulo del elemento seleccionado en la lista.
Veamos:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sincronizar el estado del drawer
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Cambiar las configuraciones del drawer si hubo modificaciones
drawerToggle.onConfigurationChanged(newConfig);
}
Dentro de onPostCreate() usaremos el mtodo syncState() para sincronizar el estado del
toggle si en algun momento la aplicacin es puesta en segundo plano. Y en
onConfigurationChanged() propagaremos los cambios del dispositivo.
Adicionalmente puedes tomar accin cuando el toggle sea presionado en la action bar con
el mtodo onOptionsItemSelected(), igual a como se hace con los action buttons:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
// Toma los eventos de seleccin del toggle aqu
return true;
}
return super.onOptionsItemSelected(item);
}
Para terminar ejecuta el proyecto y tendrs tu aplicacin GeekyWeb con el siguiente
aspecto: