DesarrolloLibre

Desarrollo Web, Android, juegos 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

Generador de launcher para Android sin padding

Generador de launcher para Android sin padding

Templates para Android y iOS

Templates para Android y iOS

Librería oficial de PayPal para Android

Librería oficial de PayPal  para Android

Algunos artículos que te pueden interesar

¿Cómo instalar el ADT Bundle de Android?

¿Cómo instalar el ADT Bundle de Android?

El ADT Bundle nos permite desarrollar aplicaciones para Android rápidamente; nos ofrece un entorno de desarrollo ya completo e integrado sin necesidad de hacer alguna configuración previa o posterior a su instalación.

Andrés Cruz 02-09-2013

¿Cómo importar una librería (jar) en Android?

¿Cómo importar una librería (jar) en Android?

En este artículo explicaremos algunas de las diferentes forma que hay para importar las librerías JAR en un proyecto Android, utilizando eclipse y el plugin ADT.

Andrés Cruz 21-09-2013

Incluyendo fragments dentro de otros fragment en Android

Incluyendo fragments dentro de otros fragment en Android

Se explica cómo embeber fragments dentro de otros fragments en Android y se explica un posible propósito de esta idea.

Andrés Cruz 26-12-2016