Fundamentos de Android: Introducción a los Fragmentos

Fundamentos de Android: Introducción a los Fragmentos

Android introduce los fragmentos en Android 3.0 (nivel de API 11) principalmente para admitir diseños de la interfaz de usuario (IU o UI, de user interface) más dinámicos y flexibles en pantallas grandes, como las de las tablets, dividiendo el diseño de una actividad en fragmentos, lo que permite modificar el aspecto de la actividad en tiempo de ejecución.

Un fragmento (fragment) representa una parte de la IU en una actividad. Podemos combinar múltiples fragmentos en una sola actividad para construir una IU compleja,
y reutilizar un fragmento en distintas actividades. Podemos pensar en un fragmento como una sección modular de una actividad, que tiene su propio ciclo de vida, que recibe sus propios eventos de entrada y que se puede agregar o quitar mientras la actividad se está ejecutando, algo así como una "subactividad" que se volver a usar en diferentes actividades. En definitiva, un fragmento es un componente de Android que puede contener parte del comportamiento y de la IU de una actividad, a la que está vinculado.

Y es que un fragmento siempre debe estar integrado en una actividad (no son entidades independientes) y el ciclo de vida del fragmento se ve directamente afectado por el ciclo de vida de la actividad anfitriona (en próximas entradas hablaremos del ciclo de vida de la actividad). Por ejemplo, cuando la actividad está pausada, también lo están todos sus fragmentos, y cuando la actividad se destruye, lo mismo ocurre con todos los fragmentos. Sin embargo, mientras una actividad se está ejecutando se puede manipular cada fragmento de forma independiente, por ejemplo, para agregarlos o quitarlos.

Debemos diseñar cada fragmento como un componente modular y reutilizable de la actividad, pudiendo cambiar las combinaciones de fragmentos para diferentes tamaños de pantalla y reutilizando los fragmentos en diferentes configuraciones de diseño para optimizar la experiencia del usuario en función del espacio de pantalla disponible. La siguiente imagen representa la manera en que dos módulos de la IU definidos por fragmentos se pueden combinar en una actividad para un diseño de tablet y se presentan por separado para un diseño de teléfono en, por ejemplo, una aplicación de noticias que usa un fragmento para mostrar una lista de artículos a la izquierda y otro fragmento para mostrar el artículo seleccionado a la derecha:



En resumen, los fragmentos en Android aportan:
  • Modularidad: División del código de una actividad compleja en fragmentos para una mejor organización y mantenimiento.
  • Reusabilidad: Al ubicar un comportamiento o parte de la IU en fragmentos, éstos pueden ser compartidos por múltiples actividades.
  • Adaptabilidad: La representación de secciones de la IU como fragmentos permite utilizar diferentes diseños según la orientación y el tamaño de la pantalla.

En esta entrada vamos a aprender a crear un fragmento a través de un ejemplo básico, y en próximas entradas veremos cómo los fragmentos pueden enviar información a una actividad y cómo añadir y remplazar fragmentos.

Empezamos creando un nuevo proyecto desde una actividad vacía. Una manera rápida de crear un fragmento es enfocar el panel de archivos del proyecto seleccionando, por ejemplo, la carpeta com.android.miapp y desde el menú superior accedemos a File -> New -> Fragment -> Fragment (Blank) o bien con el botón secundario del ratón com.android.miapp -> New -> Fragment -> Fragment (Blank):



Esto abre la ventana New Android Component, donde asignamos un nombre al fragmento y desactivamos las casillas de verificación relativas a factory methods e interface callbacks como se ve en la imagen:



Comprobamos que al crear el fragmento tenemos un nuevo archivo de Kotlin y su correspondiente archivo de diseño XML con un TextView. Repetimos para crear un segundo fragmento. Configuramos los archivos de diseño de ambos fragmentos con algunos atributos distintos (color de fondo y texto) para distinguirlos más fácilmente en el diseño de la actividad, quedando de esta manera:
<!-- layout/fragment_primer_fragmento.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="@color/colorAccent"
    tools:context=".PrimerFragmento">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="@dimen/padding_4"
        android:text="@string/primer_fragment"
        android:textSize="18sp" />

</FrameLayout>
<!--layout/fragment_segundo_fragmento.xml-->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="@color/colorPrimary"
    tools:context=".SegundoFragmento">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="@dimen/padding_4"
        android:text="@string/segundo_fragment"
        android:textSize="18sp" />

</FrameLayout>

Ahora abrimos el archivo activity_main.xml para añadir ambos fragmentos como parte del diseño de la actividad principal, lo que podemos hacer con la etiqueta <fragment> en vista Text o más fácilmente en vista Design, arrastrando desde la paleta de elementos el elemento <fragment> hasta el árbol de componentes (al hacerlo, Android Studio preguntará cuál de los fragmentos creados queremos añadir):



Eliminamos el TextView que viene por defecto y distribuimos los fragmentos en la pantalla dentro del ConstraintLayout:
<!--layout/activity_main.xml-->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/fragment"
        android:name="com.android.miapp.PrimerFragmento"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/fragment2"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <fragment
        android:id="@+id/fragment2"
        android:name="com.android.miapp.SegundoFragmento"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/fragment"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Al ejecutar la aplicación en el emulador podemos ver un resultando semejante a éste:



En esta entrada introductoria hemos visto cómo crear y añadir un fragmento a una actividad, pero lo hemos hecho de un modo estático, cuando los fragmentos permiten variaciones en el diseño en tiempo de ejecución. Próximamente veremos cómo crear y usar fragmentos dinámicamente desde la actividad con FragmentManager y cómo realizar transacciones de fragmentos.

Comentarios

Entradas populares

Recursos gratis para aprender Kotlin

I/O: entrada y salida de datos en consola

Lectura y escritura de archivos