Last Updated: 2021-31-05

Interfaces gráficas en Android

La interfaz de usuario de una aplicación es todo aquello que el usuario puede ver y con lo que puede interactuar. Para diseñar interfaces gráficas de aplicaciones móviles se requieren distintos tipos de vistas que brinden una experiencia agradable y familiar al usuario. Además de las vistas, es necesario definir un flujo de aplicación que maximice la usabilidad y la facilidad de interacción con el usuario. Para manejar estos flujos Android ofrece una estructura de navegación sólida con base en componentes denominados Actividades y Fragmentos. Estos componentes representan una pantalla de la aplicación, y los cuales se comunican por medio de Intents, manejadores y de la navegación de Jetpack.

Dada la naturaleza del sistema operativo de Android, estos componentes de interfaz gráfica manejan ciclos de vida complejos donde se definen eventos de creación, pausa, reinicio y finalización de la aplicación para asegurar un correcto manejo de los recursos del dispositivo móvil en cuanto a la carga de información y renderizado de la interfaz. Por este motivo, es muy importante conocer y comprender el funcionamiento de dichos componentes en detalle.

¿Qué construirá?

Al final de este tutorial usted tendrá:

¿Qué aprenderá?

Al desarrollar este tutorial aprenderá:

¿Qué necesita?

Componentes fundamentales de una aplicación de Android

La arquitectura de una aplicación Android se define por medio de componentes estándar, definidos de forma particular para el sistema operativo Android. Estos componentes se catalogan en Actividades, Servicios, Receptores de emisiones, Proveedores de contenido, los cuales se detallan a continuación:

Estos componentes pueden tener múltiples variaciones si se utilizan sus subclases, definidas en las librerías de Android. Para incluir cualquiera de estos en la aplicación, es necesario incluirlo en un archivo denominado el archivo de manifiesto, el cual permite definir el esqueleto de una aplicación XML por medio de etiquetas con propiedades. Si desea conocer más sobre el archivo de manifiesto, consulte el siguiente enlace: https://developer.android.com/guide/topics/manifest/manifest-intro?hl=es-419.

Actividades de Android

Como se indicó previamente, las actividades representan una pantalla de la interfaz gráfica del usuario. Estas son los puntos de interacción principales del usuario y, generalmente, son el punto de partida de una aplicación Android, ya que al abrir la aplicación el sistema operativo busca la actividad principal definida en el archivo de manifiesto y lanza un Intent con la acción Launch.

Las actividades pueden asimilarse como las distintas URLs de una aplicación web (exceptuando el caso de las SPA o Single Page Applications), dado que son pantallas de la aplicación que pueden ser accedidas de forma directa en algunas ocasiones, y suelen ser lanzadas con alguna información como argumento (por medio de los Extras, en Android, o los Path Params en web).

Así, es posible definir múltiples actividades que reciban Intents personalizados para cada caso. Para esto, se debe asociar un intent-filter a la actividad, con sus respectivas acciones, categorías y datos. Todo lo anterior se logra definiendo las actividades en el archivo de manifiesto por medio de la siguiente estructura:

<manifest ... >
      <application ... >
          <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
          </activity>

          ...
      </application ... >
      ...
</manifest >

Note que las distinciones de categoría, acciones y datos son constantes de Android, por lo cual es necesario adaptarse a las definiciones indicadas en la documentación oficial, disponible en este enlace: https://developer.android.com/guide/topics/manifest/manifest-intro?hl=es-419#reference, para poder utilizar Intents que el sistema operativo comprenda. Note, también, que la definición de la actividad debe corresponder con un archivo con el mismo nombre. En este archivo, la actividad se define únicamente definiendo una clase que herede de Activity. Para llamar a una actividad con un intent-filter es necesario lanzar el Intent desde otra fuente, de la siguiente forma:

val sendIntent = Intent().apply {
        action = Intent.ACTION_SEND
        type = "text/plain"
        putExtra(Intent.EXTRA_TEXT, textMessage)
    }
    startActivity(sendIntent)

Finalmente, en la clase que contiene la actividad, se debe definir la vista vinculada en los archivos de recursos xml utilizando el método setContentView y asociar la funcionalidad de los elementos de la vista. Adicionalmente, también es posible definir acciones para controlar los distintos momentos del ciclo de vida de la aplicación. Para comprender el ciclo de vida de una actividad, observe el siguiente diagrama, tomado de la documentación oficial sobre el ciclo de vida de actividades, disponible en el siguiente enlace: https://developer.android.com/guide/components/activities/activity-lifecycle.

Flujo: Actividad lanzada, llamado a los métodos onCreate, onStart, onResume respectivamente para que la actividad pase a estar corriendo. Si llega otra actividad, se llama onPause. Si se retorna a la actividad, llama onResume, si no es más visible, llama onStop. Si otra app requiere memoria, muere el proceso y debe volver a crearse. Si se termina la actividad, llama onDestroy.

Imagen 1. Diagrama del ciclo de vida de la actividad

Para el caso de este tutorial, se utilizará una aplicación que representa un diccionario de palabras en inglés, que cuenta con una lista con las letras del abecedario para organizar las palabras y una vista con las palabras que comienzan con una letra particular, desde la cual se puede consultar el significado en Google. Este caso de estudio se basa en los codelabs de Activites and Intents (disponible en el siguiente enlace: https://developer.android.com/codelabs/basic-android-kotlin-training-activities-intents#1) y Fragments and Navigation component (disponible en el siguiente enlace: https://developer.android.google.cn/codelabs/basic-android-kotlin-training-fragments-navigation-component#1)

Conocer las pantallas de la aplicación

Las vistas mencionadas anteriormente se verán, inicialmente, de la siguiente forma:

Primera pantalla: words, un listado de letras para filtrar las palabras. Segunda pantalla: Words that start with, un listado de palabras que comienzan por la letra elegida en la anterior vista. Tercera pantalla: búsqueda de la palabra en google con el navegador.

Imagen 3. Pantallas resultantes de la aplicación

Obtener el código fuente de la aplicación

El código inicial del proyecto se encuentra alojado en un repositorio de GitHub, al cual puede acceder desde el siguiente enlace: https://github.com/google-developer-training/android-basics-kotlin-words-app/tree/starter. Ingrese al enlace anterior para ver el código del proyecto en la rama starter. Como con todos los proyectos de GitHub, usted puede descargar los archivos del repositorio a su máquina local por varios medios.

Si lo desea, puede optar por descargar el código fuente directamente en forma de archivo .zip desde la página web del repositorio en GitHub, haciendo clic en el botón "Download Zip" del desplegable Code, el cual se ve en la siguiente imagen:

Sección del sitio web del repositorio donde se muestran las diferentes opciones para descargar el código del proyecto> Clone, Open with Github Desktop, Download ZIP

Imagen 4. Vista desplegable del botón Code

No obstante, si cuenta con GitHub Desktop, puede hacer clic en el botón Open with GitHub Desktop. Si cuenta con Git instalado localmente en su máquina, puede clonar el repositorio a un directorio local vacío por medio del comando git clone https://github.com/google-developer-training/android-basics-kotlin-words-app.git, o por medio de la interfaz gráfica de Git. Finalmente, también puede optar por descargar el proyecto directamente con Android Studio haciendo uso de la opción Get from Version Control del menú inicial de Android Studio, la cual se muestra en la siguiente imagen:

Al abrir Android Studio sin un proyecto se muestra un menú con varios botones para abrir o importar un proyecto, perfilar un APK o abrir configuraciones del IDE

Imagen 5. Menú de inicio de Android Studio

En caso de clonar el repositorio completo y ubicarse de forma predeterminada en la rama master, ejecute el comando git switch starter.

Ejecutar la aplicación en su dispositivo

Una vez haya importado el proyecto en Android Studio, el siguiente paso es ejecutar la aplicación para hacer una instalación en modo debug en su dispositivo físico o virtual.

Si cuenta con un dispositivo físico con el sistema operativo Android, debe asegurarse de que este tenga activas las opciones de desarrollador y que esté habilitado para la depuración con Android Debug Bridge (ADB). Para lograr esto, siga las instrucciones del enlace: https://developer.android.com/studio/debug/dev-options. Una vez su dispositivo esté configurado, solo debe conectarlo a su computador por medio de un cable USB. Android Studio automáticamente detectará los dispositivos conectados, pero usted también podrá verificar que ADB reconozca a su dispositivo por medio de la consola ejecutando el comando adb devices; esto reiniciará el servidor de ADB en su computadora y determinará si se puede establecer una conexión.

Si no cuenta con un dispositivo físico, tendrá que crear un dispositivo virtual. Este procedimiento puede requerir pasos extra según el sistema operativo, los cuales puede averiguar en el siguiente enlace: https://developer.android.com/studio/run/emulator. Por defecto, Android Studio mostrará al emulador como primera opción para ejecutar la aplicación, siempre y cuando exista uno.

Una vez haya establecido la conexión con el dispositivo objetivo, podrá ver el nombre del mismo en la parte superior junto a los botones de acciones rápidas. Ahora, ejecute la aplicación presionando el botón Run, con un ícono de flecha verde para compilar y ejecutar la aplicación.

En el panel "Build" de la parte inferior podrá ver un listado de acciones que comprenden esta ejecución. Gran parte de estas acciones tienen que ver con la construcción del proyecto y sus dependencias en Gradle, y se corren en segundo plano, así que puede seguir explorando el contenido de la aplicación en el Integrated Development Environment (IDE).

Luego de unos segundos, la aplicación se ejecutará en su dispositivo y podrá ver en la pantalla la interfaz de la primera pantalla con el listado de letras.

En este punto, usted descargó un esqueleto de código fuente, y lo ejecutó como aplicación en un dispositivo Android. Este código es una base inicial, y por ende, está incompleto. Al interactuar con la aplicación pudo notar que no era completamente funcional. Por este motivo, usted va a realizar modificaciones a la aplicación, definiendo las pantallas indicadas por medio de actividades (únicamente), las cuales se comunicarán entre sí por medio de Intents.

Definir los cambios a implementar

Una vez tenga abierto el código del proyecto en Android Studio, explore sus contenidos. Fíjese que en el directorio de código fuente (src) del paquete com.example.wordsapp existen dos actividades y sus dos respectivos adaptadores para los RecyclerView.

Los archivos con los que se trabajará en esta primera etapa son los siguientes:

Implementar el llamado entre actividades por medio de Intents

En primer lugar, abra el archivo LetterAdapter para definir la función que tendrán los botones correspondientes a cada una de las letras. Esta función consiste en abrir la actividad definida en DetailActivity con los parámetros respectivos a la letra seleccionada. Esto es decir únicamente que en el click listener del botón se definirán líneas de código donde se instancie y lance un Intent. Esta definición debe suceder en el método onBindViewHolder() y es necesario realizarla por medio del método setOnClickListener del elemento holder.button.

El llamado a la nueva actividad se realizará con un Intent normal cuyo contexto es el View Holder y su único parámetro es la letra. Esto se representa con el siguiente código fuente:

val context = holder.view.context
val intent = Intent(context, DetailActivity::class.java)
intent.putExtra("letter", holder.button.text.toString())
context.startActivity(intent)

Además de programar el llamado del Intent, es necesario que programe su recepción por parte de la otra actividad. En el archivo de manifiesto encontrará los intent-filter necesarios, pero en el archivo DetailActivity hace falta definir el comportamiento en términos de lo que se hará con la información recibida de dichos Intents. Abra este archivo y en el método onCreate, después del llamado al método setContentView, reemplace el valor de la variable letterId por el siguiente:

val letterId = intent?.extras?.getString("letter").toString()

Note que el identificador intent existe a pesar de no ser explícitamente declarado, ya que DetailActivity hereda de la clase Activity, y esta es una propiedad de la superclase. No obstante, se utilizan operadores de validación de nulidad, ya que no existe certeza a priori de cómo será el Intent o sus contenidos.

Implementar la búsqueda de palabras con otra aplicación por medio de Intents

Lo segundo que debe lograr es la comunicación de su aplicación con cualquier otra aplicación que sepa manipular los Intents relacionados a una búsqueda de URLs en internet (típicamente, los navegadores web). En este caso el Intent será implícito, ya que no se sabe con exactitud cuál será la aplicación destinataria del mismo. La definición de esta operación debe hacerla en el click listener del botón correspondiente a cada palabra, en la pantalla del listado de palabras que comienzan con una letra. Abra el archivo WordAdapter y configure el listener del botón para que contenga el siguiente código fuente:

holder.button.setOnClickListener {
    val queryUrl: Uri = Uri.parse("https://www.google.com/search?q=${item}")
    val intent = Intent(Intent.ACTION_VIEW, queryUrl)
    context.startActivity(intent)
}

Ejecutar la aplicación luego de las modificaciones

Una vez haya realizado los cambios de este paso del tutorial, vuelva a ejecutar la aplicación en su dispositivo móvil, haciendo clic en el botón Run de Android Studio e interactúe con las pantallas de la aplicación. Note que el comportamiento es bastante sencillo y que, a diferencia de la aplicación que descargó inicialmente, existe un flujo entre las distintas pantallas, de forma que existe cierta funcionalidad de búsqueda.

¡Felicidades!

Al realizar este tutorial pudo familiarizarse con los conceptos de Actividades en Android, los ciclos de vida de las actividades y el envío de información por medio de Intents.

Ahora podrá implementar sus propias actividades en una aplicación de Android que contenga varias pantallas, establecer una comunicación adecuada entre ellas y ahondar en las particularidades del desarrollo con Kotlin para crear aplicaciones modernas y cada vez más complejas.

¿Qué sigue?

Revise los tutoriales para crear aplicaciones con varias vistas usando fragmentos y cómo aplicar temas. Recuerde que esta era la primera parte de la serie de tutoriales para familiarizarse con los componentes de navegación y los de estilos de una aplicación de Android.

Créditos

Versión 1.1 - Mayo 31, 2021

Juan Sebastián Espitia Acero

Autor

Norma Rocio Héndez Puerto

Revisora

Mario Linares Vásquez

Revisor