DesarrolloLibre

Desarrollo Web, Android y mucho más

13-07-2016

Uno de los grandes objetivos en el desarrollo de software en general es que las aplicaciones a realizar sean modulares que puedan ser reutilizadas fácilmente, adaptar nuevos módulos, etc; una forma de lograr esto en Android que en esta entrada es nuestro caso de interés es con los fragments lo de los cuales podemos decir que:

Un fragment representa una porción, sección o módulo de una interfaz de usuario en una actividad:
fragments en android

Aunque veremos que cada vez que vamos encapsulando más y más la aplicación se nos cierran las posibilidades más comunes realizar la comunicación entre los módulos y por lo tanto de construir la aplicación en general; uno de estos casos es cuando deseamos listar varios fragments en una misma actividad (recordemos que una actividad puede contener uno o más fragments), una forma de hacer esto es mediante tabs; al estar en este punto nos daremos cuenta que ya estamos encapsulado nuestro fragment dentro otro módulo (o mejor dicho un elemento que provee la API de Android para crear vistas deslizables); todo esto nos trae un mayor nivel de complejidad del ya complejo manejo que tiene Android al momento de programar una aplicación (por ejemplo la por si molesta instancia de la actividad <<actitity>> que debemos emplear en una gran cantidad de funciones como parámetro obligatorio:

Ejemplo de un código con el objeto Activity

En esta entrada veremos un simple caso de cómo podemos establecer varios fragments en tags y de esta forma crear vistas deslizables, además de poder cambiar de un fragment a otro cuando lo deseemos.

Creando nuestras vistas deslizables con Tags y fragments

El experimento consiste en crear tres fragments y vincularlos directamente a los tags que los contendrán; además podremos reemplazar el contenido del fragment facilmente en cualquier ubicación que deseemos como veremos más adelante.

Fragment 1

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:background="#FF0000"
   tools:context="com.insta.andre.tagfragment.MainActivity">

  
   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:text="UNO"
       android:gravity="center_vertical|center_horizontal"
       android:textSize="50dp"/>
</RelativeLayout>

Fragment 2

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#00FF00"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.insta.andre.tagfragment.MainActivity">


   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center_vertical|center_horizontal"
       android:text="DOS"
       android:textSize="50dp" />

   <Button
       android:id="@+id/cambiar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:text="Cambiar a fragment 3" />
</RelativeLayout>

Fragment 3

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#0000FF"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.insta.andre.tagfragment.MainActivity">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center_vertical|center_horizontal"
       android:text="TRES"
       android:textSize="50dp" />

   <Button
       android:id="@+id/cambiar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Cambiar a fragment 2"
       android:layout_alignParentBottom="true"/>

</RelativeLayout>

Cómo vemos el contenido de los fragments son prácticamente iguales salvo por el contenido del TextView y un par de fragments tienen un botón que configuraremos más adelante; desde nuestra actividad tendremos que definir un layout como el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.insta.andre.tagfragment.MainActivity">

   <TabHost android:id="@android:id/tabhost"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >

       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent" >

           <FrameLayout
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:padding="5dp"
               android:layout_weight="1"
               android:id="@android:id/tabcontent" >

               <FrameLayout android:id="@+id/tab1"
                   android:orientation="vertical"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent" >
               </FrameLayout>

               <FrameLayout android:id="@+id/tab2"
                   android:orientation="vertical"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent" >
               </FrameLayout>
           </FrameLayout>

           <TabWidget
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:layout_weight="0"
               android:layout_marginBottom="-4dp"
               android:id="@android:id/tabs" />
       </LinearLayout>
   </TabHost>

</RelativeLayout>

Como puedes ver en la siguiente imagen y comparando el código anterior, nuestro sistema de tags estará compuesto por dos tags; cada uno de ellos contendrá a un fragment:

<TabHost id=tabhost">
    <FrameLayout id="tabcontent">
        <FrameLayout id="tab1">
        </FrameLayout>
        <FrameLayout id="tab2">
        </FrameLayout>
    </FrameLayout>
    <TabWidget id="tabs" />
</TabHost>

Con el código anterior puedes darte una idea de como es el esquema en general de los tags en Android; como podras darte cuenta, simplemente debemos seguir un patrón ya definido, ahora necesitamos establecer desde la actividad cada uno de los fragments en los tags:

TabHost tabs = (TabHost) findViewById(android.R.id.tabhost);
tabs.setup();

TabHost.TabSpec spec = tabs.newTabSpec("mitab1");
spec.setContent(R.id.tab1);
spec.setIndicator("TAB1");
tabs.addTab(spec);

spec = tabs.newTabSpec("mitab2");
spec.setContent(R.id.tab2);
spec.setIndicator("TAB2");
tabs.addTab(spec);

tabs.setCurrentTab(0);

if (savedInstanceState == null) {
   getSupportFragmentManager().beginTransaction()
           .add(R.id.tab1, new UnoFragment())
           .commit();

   getSupportFragmentManager().beginTransaction()
           .add(R.id.tab2, new DosFragment())
           .commit();
}

Llegado a este punto te preguntarás por qué creamos tres fragments si sólo empleamos dos, pues si has trabajado con alguna aplicacion Android que consuma servicios desde otra plataforma o que consten de diversas categorías en donde una categoría es el padre o está a un mayor nivel esto nos llevaría a reemplazar el contenido del padre al aplicar alguna selección que generalmente este reemplazo de fragments sería a través de un gridview o listview pero para mantener simple nuestro ejemplo no empleamos ningún otra vista agrupada.

En general lo que queremos hacer es reemplazar el fragment 2 con el fragment 3 y viceversa; lo podemos hacer empleando el evento onclick desde el fragment 2/3 a través de un botón empleando el siguiente código:

DosFragment dosFragment = new DosFragment();
FragmentManager fragmentManager = myContext.getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.tab2, dosFragment).addToBackStack(null).commit();

Como vemos es muy simple, reemplazamos por el identificador de la vista que en nuestro caso es tab2, esta sección de código lo podemos llamar fácilmente dede otras clases relacionadas o vistas agrupadas como lo son gridview, listview o el recyclerview.

Aunque como se indicó en un inicio, no sería del todo correcto colocar este tipo de lógica en un fragment (los fragments por definición deben ser independientes unos de otros) para nuestro caso práctico empleamos esta solución.

Puedes encontrar el código completo en el repositorio de GIT al inicio y final de esta entrada.


Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Creando increibles Drawer en Android con MaterialDrawer

Creando increibles Drawer en Android con MaterialDrawer

Librería oficial de PayPal para Android

Librería oficial de PayPal  para Android

Paleta de colores para el Material Design

Paleta de colores para el Material Design

Algunos artículos que te pueden interesar

Puntos de Interés (POI) con Realidad Aumentada en Wikitude

Puntos de Interés (POI) con Realidad Aumentada en Wikitude

En este artículo veremos cómo marcar un sitio a través de Puntos de Interés (POI); en otras palabras reconocer una zona por su posicionamiento geográfico.

Andrés Cruz 16-04-2014

Lo nuevo del Material Design: Los RecyclerView

Lo nuevo del Material Design: Los RecyclerView

Los RecyclerView al igual que los GridView y ListView, permite crear listados de ítems ya sea a través de listas o celdas y son una versión más flexible, potente y actualizada que los GridView ListView.

Andrés Cruz 07-10-2015

El elemento symbol para los SVG en HTML

El elemento symbol para los SVG en HTML

En esta entrada veremos un elemento muy útil para trabajar con los SVG que es el elemento symbol; este elemento ahorra mucho trabajo y permite agrupar una serie de figuras básicas y pintarlos empleando el elemento use.

Andrés Cruz 01-06-2015