Tweakr: Prototipado y control remoto de El mago de Oz con Firebase y Android

1. Introducción

Última actualización: 30/03/2022

Una biblioteca para depurar y generar automáticamente las IU de preferencias y los prototipos de El mago de Oz de forma remota

¿Te cansaste de ajustar un valor de tu animación y tener que esperar minutos para compilar y ver el cambio? ¿Alguna vez quisiste entregarle un prototipo a alguien y permitirles que lo prueben con varias opciones que puedas ajustar sobre la marcha? ¿Sientes un hormigueo cada vez que alguien menciona una "solución de una línea"? Entonces, Tweakr puede ser la opción adecuada para ti.

Tweakr es una biblioteca de Android que te permite anotar campos y métodos en tu código, y, luego, genera una IU automáticamente para cambiar esos elementos de forma local o remota. Puede usar Firebase y una IU basada en la Web a fin de modificar los valores y cambiar la configuración de tu app al instante. También puede generar de forma automática una pantalla de IU de Preferencias mediante SharedPreferences locales en el teléfono.

Todo lo que debes hacer es escribir una línea de código: anota lo que quieras cambiar con @Tweak, y esta se encargará del resto.

c407af6de21474.gif

Qué compilarás

En este codelab, compilarás una app para Android sencilla. Tu app hará lo siguiente:

  • Dibujar algunas imágenes y texto en la pantalla
  • Anotar campos y métodos en tu app con la anotación @Tweakr
  • Conectar la IU web de Tweakr mediante Firebase (la IU web ya está compilada y lista para que la uses)
  • Usar Tweakr a fin de manipular las vistas y moverlas por la pantalla

Qué aprenderás

  • Cómo configurar Firebase en tu app para Android
  • Cómo anotar campos y métodos en tu app de modo que Tweakr genere la IU a fin de controlarlos

Este codelab se enfoca en el uso de la biblioteca de Tweakr. Los conceptos que no son relevantes y los bloques de código se pasan por alto y se te brindan para que solo copies y pegues.

Requisitos

  • Una computadora que tenga Android Studio instalado
  • Conocimientos básicos sobre Android y las Vistas en Kotlin

2. Crea y configura un proyecto de Firebase

Tweakr crea IU que conectan automáticamente tu app para Android a una IU web mediante Firebase. Primero, deberás configurar un proyecto de Firebase para Android.

Cómo crear un proyecto de Firebase

  1. Accede a Firebase.
  2. En Firebase console, haz clic en Add proyect (o Create a proyect) y, luego, asígnale el nombre Tweakr-Codelab. cd5d93d8733c5730.png
  3. Haz clic en las opciones de creación del proyecto. Si se te solicita, acepta las condiciones de Firebase. Omite la configuración de Google Analytics, ya que no utilizarás ese servicio en esta app.

Para obtener más información sobre los proyectos de Firebase, consulta la Información sobre los proyectos de Firebase.

Cómo configurar una app para Android en Firebase

  1. En Firebase console, agrega una nueva app para Android con tu propio nombre de paquete (p. ej., com.[your-domain].tweakr.sample). Campos como nombre del paquete y claves de depuración Botón Register app
  2. Sigue las instrucciones a fin de descargar el archivo google-services.json.
  3. Copia el archivo google-services.json en el directorio del módulo app de la app para Android (p. ej., tweakr-codelab/app/).
  4. Omite la confirmación de la conexión a Firebase. Harás eso una vez que actualices ApplicationId en la app para Android.
  5. Haz clic en Gradle Sync como se indica.

Cómo habilitar los productos de Firebase en la consola

La app que estás compilando usa varios productos de Firebase que están disponibles para aplicaciones web:

  • Firebase Authentication y la IU de Firebase permiten que los usuarios accedan a tu app de manera sencilla.
  • Tweakr usa Realtime Database para sincronizar datos al instante entre tu app y la IU web.
  • Las reglas de seguridad de Firebase protegen tu base de datos.

Algunos de estos productos necesitan una configuración especial o deben habilitarse mediante Firebase console.

Cómo habilitar el acceso anónimo en Firebase Authentication

A fin de permitir que los usuarios accedan a la aplicación web, usarás el método de acceso anónimo en este codelab:

  1. En Firebase console, haz clic en Authentication, que se encuentra en la opción Build, en el panel izquierdo.
  2. Haz clic en Authentication y, luego, en la pestaña Get Started -> Sign-in method (o haz clic aquí para ir directamente a la pestaña Método de acceso).
  3. En la lista de proveedores de acceso, haz clic en Anonymous, establece el interruptor Enable en la posición de activado y, luego, haz clic en Save. d7a9ec05ba37f407.png

Cómo habilitar Realtime Database

Tweakr usa Realtime Database para sincronizar el estado entre tu app y la IU web muchas veces por segundo.

Habilita Realtime Database de la siguiente manera:

  1. En la sección Build de Firebase console, haz clic en Realtime Database.
  2. Haz clic en Create database. 21491f6ad60c0f3.png
  3. Selecciona la ubicación de tu base de datos (puedes usar la predeterminada). Ten en cuenta que esta ubicación no se podrá cambiar más adelante. 32f815f4648c3174.png
  4. Selecciona la opción Start in test mode para asegurarte de que puedas escribir con libertad en la base de datos durante el desarrollo. Lee la renuncia de responsabilidad sobre las reglas de seguridad y, luego, haz clic en Next. acfcf535bff30f47.png
  1. Haz clic en Enable.

3. Compila la app de ejemplo de Android

Obtén el código

Todo lo que necesitas con relación a este proyecto se encuentra en un repositorio de Git. Para comenzar, deberás obtener el código y abrirlo en Android Studio.

Recomendación importante: Usa Android Studio a fin de importar el repositorio

  1. Abre Android Studio y selecciona File > New > Project en la sección Version control.
  2. Elige Git como la opción de control de versión.
  3. Ingresa la URL https://github.com/google/tweakr-codelab.git.
  4. Haz clic en Clone.

Actualiza ApplicationId

Dado que Firebase requiere un ApplicationId único para tu app para Android, deberás cambiar el nombre del ejemplo a tu propio ApplicationId:

  1. Abre el archivo app/build.gradle del módulo Tweakr_codelab.app.
  2. Cambia la línea applicationId "com.yourdomain.tweakr.sample" por el nombre del paquete que especificaste en la configuración de Firebase.
  3. Haz clic en ApplicationId a fin de sincronizar los cambios con el archivo de Gradle.

Ejecuta la app

  1. Haz clic en Run para compilar e iniciar la app tal como está. Si usas Android Emulator, asegúrate de crear una imagen de AVD desde las bibliotecas de Google Play, que son necesarias para Firebase.

6f6d2c9539143a5a.png

Deberías ver una pantalla simple en la app con texto y un círculo.

  1. Haz clic en el texto a fin de activar una animación.

4. ¡Comencemos con Tweakr!

Al final de esta sección, podrás controlar de forma remota las vistas en nuestra app desde el sitio web de Tweakr.

Agrega la dependencia de la biblioteca de Tweakr

  1. Abre el archivo settings.gradle y agrega Jitpack a los repositorios:

settings.gradle

dependencyResolutionManagement {
   repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
   repositories {
       google()
       mavenCentral()
       maven { url 'https://jitpack.io' }
   }
}
  1. Abre el archivo app/build.gradle del módulo Tweakr_codelab.app y agrega las dependencias de la biblioteca de Tweakr:

app/build.gradle

dependencies {

...

   // Required for local SharedPreferences or Firebase
   implementation 'com.github.google.tweakr:core:2.2.2'

   // Include this if you want Firebase support.
   implementation 'com.github.google.tweakr:firebase:2.2.2'
}
  1. Haz clic en Sync Now a fin de sincronizar los cambios de Gradle.

Inicializa el repositorio de Tweakr

En primer lugar, debes inicializar el repositorio de Tweakr en el método onCreate() de SampleApplication para que sepa que debe usar Firebase:

  1. Abre el archivo SampleApplication.kt.
  2. Quita los comentarios de la línea que dice Tweakr.setRepo(TweakrFirebaseRepo()).

Esto le indica a Tweakr que debe usar el TweakrFirebaseRepo para sincronizar sus valores con la nube. TweakrFirebaseRepo usa automáticamente la instancia de Firebase predeterminada, que se define mediante el archivo google-services.json que agregaste en la primera sección.

Haz algunos ajustes

Ya está todo listo para comenzar a anotar partes de la app de modo que Tweakr pueda generar una IU web para ellas.

  1. En el archivo MainActivity.kt, arriba de la línea fun animateText(), agrega la anotación @Tweak. Esto le indica a Tweakr que quieres controlar este método de forma remota.

MainActivity.kt

@Tweak
fun animateText() {
 introText.animate()
...
}
  1. En la parte inferior de la función onCreate(), agrega la línea Tweakr.register(this). Esto le indica a Tweakr que debe analizar todas las anotaciones de la clase y sincronizar sus valores con el servidor web.

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 introText = findViewById(R.id.text)
 introText.setOnClickListener { animateText() }

 Tweakr.register(this)
}
  1. Ahora, vuelve a ejecutar la app.

Si todo salió bien, Tweakr se inicializó en segundo plano y sincronizó nuestros ajustes con el servidor de Firebase. En la próxima sección, descubrirás la magia de lo que hiciste.

5. Ajusta los valores en la IU web

Ahora que configuraste algunos valores ajustables de tu app, puedes abrir la IU web de Tweakr para controlarlos de forma remota por Internet. La manera más sencilla de comenzar a modificar los valores es usar el sitio web compilado previamente de Tweakr llamado Easyserver. Este sitio web está alojado en GitHub y se conecta a tu base de datos de Firebase a fin de sincronizar los valores y generar la IU web desde tu app para Android.

Configura una aplicación web en Firebase

En primer lugar, debes configurar una aplicación web en Firebase y otorgarle acceso a Easyserver.

  1. En Firebase console, haz clic en Descripción general del proyecto.
  2. Haz clic en Add app y elige Web. 82b936ff2bbbbbac.png
  3. Ingresa un sobrenombre y haz clic en Register.
  4. En el paso Add Firebase SDK, copia todo desde const firebaseConfig en adelante. En el próximo paso, lo pegarás en el Easyserver de Tweakr. c4f2e17447f8442c.png

Inicia el Easyserver

  1. Ve a https://google.github.io/tweakr/easyserver/ y sigue estas instrucciones para permitir que Easyserver acceda a Firebase:
  2. Pega el código firebaseConfig que copiaste en el paso anterior.

e8a19d25f923a76f.png

Si pegaste el código correctamente, debería mostrarte tu vínculo de acceso único y el botón Let's get Tweakin'.

  1. Haz clic en Let's get Tweakin'.

Deberías ver un botón animateText(), con el nombre de la función que anotaste antes.

7e916285f11317d4.png

El dedo en el botón

Con la app para Android abierta, haz clic en el botón animateText() en la IU web de Tweakr y mira la pantalla del teléfono.

f238f06c1cf5583e.gif

¡Increíble! Deberías ver que el texto realiza una pequeña animación. ¿Cómo sucede esto?

Puede que te preguntes: si es un botón para mi método sin parámetro, ¿qué sucede si mi método toma parámetros? Consulta la siguiente sección para averiguarlo.

6. Métodos con parámetros

Tweakr también funciona con métodos con un parámetro (aún no se admiten los métodos con más de un parámetro). Vamos a intentarlo:

  1. En la clase MainActivity, agrega un nuevo método que cambie el texto en la TextView:

MainActivity.kt

class MainActivity : Activity() {
...

 @Tweak
 fun setMessage(text: String) {
   introText.text = text
 }

...
  1. Asegúrate de agregar la anotación @Tweak a tu método nuevo.
  2. Vuelve a ejecutar la app y observa que el sitio web de Easyserver de Tweakr cambia automáticamente y muestra un campo de texto para llamar a tu método.
  3. Escribe algo en el campo de texto y observa la actualización de tu app en tiempo real.

322a56390bd5fe31.gif

Puede que controlar métodos de manera remota se muy útil, pero el verdadero poder de Tweakr es cambiar los valores de los campos en tu código. Consulta la siguiente sección y descubre más diversión.

7. Modifica los valores de los campos (opcional)

En Android Studio, abre el archivo CircleView.kt. Al parecer, hay algunos campos en la parte superior que controlan el tamaño y la posición del círculo. Hagamos esa modificación.

Agrega las anotaciones

  1. Agrega la anotación @Tweak sobre los campos centerX, centerY y radius.
  2. También debes llamar a Tweakr.register() cuando se inicialice tu objeto, por lo que debes agregar un método init(). Al finalizar, tu código debería verse de la siguiente manera:

CircleView.kt

/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

 @Tweak
 var centerX = 180f

 @Tweak
 var centerY = 180f

 @Tweak
 var radius = 50f

 init {
  Tweakr.register(this)
 }

...

Esto permite que Tweakr cambie los campos, pero aún no terminaste. Dado que se trata de una vista personalizada que se dibuja de forma directa en Canvas, cuando Tweakr cambie los valores de los campos, esta no se volverá a dibujar automáticamente con los valores nuevos. Deberás indicarle a la Vista que se vuelva a dibujar cada vez que Tweakr sincronice los cambios.

  1. Registra un objeto de escucha con Tweakr de modo que te notifique cada vez que cambie el valor de un campo de manera remota.

Para evitar fugas de memoria, también debes quitar el objeto de escucha cuando la vista no lo use. Para ello, usa los eventos attachedToWindow:

Escucha los cambios de valores de Tweakr

Anula el método onAttachedToWindow() con una llamada a Tweakr.addListener(this) y, luego, quita el objeto de escucha en onDetachedFromWindow():

CircleView.kt

/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), TweakrRepo.OnChangeListener
 {

...

  override fun onAttachedToWindow() {
   super.onAttachedToWindow()

   // Register onFieldChanged() to redraw when any value changes.
   Tweakr.addListener(this)
  }

  override fun onDetachedFromWindow() {
   Tweakr.removeListener(this)

   super.onDetachedFromWindow()
  }

  override fun onFieldChanged(name: String?, value: Any?) {
   // This is called whenever a field's value is changed in Tweakr's UI.
   // We could be granular here and check the name to match only the fields
   // we care about, but for this demo it's simple enough to just redraw
   // whenever *any* value changes.
   invalidate()
  }

...

(Debido a que estás configurando this como objeto de escucha, también debes asegurarte de que nuestra clase extienda o implemente la interfaz TweakrRepo.OnChangeListener).

Pruébalo

Ya puedes probarlo. Ejecuta la app y observa que el sitio web de Easyserver de Tweakr se actualiza automáticamente con los campos nuevos que se modificarán.

80e03628ec47917c.gif

8. Felicitaciones

¡Felicitaciones! Compilaste con éxito tu primera app con Tweakr.

Aprendiste a anotar métodos y campos con la anotación @Tweak, a llamar a Tweakr.register() en el objeto que contiene los campos y, luego, a aplicar el uso más avanzado de escuchar eventos de cambio de Tweakr a fin de poder volver a dibujar tu Vista de forma manual.

Puedes usar estas habilidades para acelerar el flujo de trabajo del prototipado, además de cambiar los valores de las animaciones sobre la marcha, controlar los prototipos de El mago de Oz de forma remota durante la investigación de UX, efectuar estudios del usuario,  etc.. Un uso común que aplicamos en nuestro equipo consistió en compartir un APK del prototipo de movimiento con nuestro diseñador de movimientos, enviarles el vínculo de la IU web de Tweakr y permitirles que ajusten los valores de la animación a su gusto (a los diseñadores de movimiento les gusta ser bastante precisos en sus valores de animación).

Nuestro equipo también creó prototipos para microinteracciones, gestos y tecnología táctil, y compartió el vínculo de Tweakr con varias configuraciones y opciones de diseño entre las que se puede alternar. Luego, crearemos un documento compartido y permitiremos que las personas completen sus valores de Tweakr favoritos, lo que contribuirá a crear un consenso sobre el diseño antes de implementarlo en la producción.

¿Qué sigue?

Otras soluciones posibles

  • Control remoto de El mago de Oz: Intenta crear un método en tu Actividad que tome una Enum de los nombres de las pantallas de tu app. Cuando Tweakr llame al método, carga un nuevo Fragmento que corresponda al nombre de la pantalla. De esa manera, podrás simplemente hacer clic en la pantalla que desees en la IU web de Tweakr, y todos los que vean la app en su teléfono verán el nuevo Fragmento. Es ideal para estudios de usuario.
  • Varios usuarios: De forma predeterminada, la IU web de Tweakr sincroniza los cambios con todas las personas que usan la app, en simultáneo. Sin embargo, cuando tengas varios usuarios simultáneos, querrás que cada uno tenga su propia sesión y que los ajustes que realicen en la IU solo afecten a su teléfono y no a los de otros usuarios. Consulta la documentación de TweakrFirebaseRepoMultiuser para crear varias sesiones con getUserKey().
  • PreferenceScreen local: Tweakr no necesita usar Firebase. También puede generar automáticamente una IU de Preferencias de Android de modo que puedas cambiar la configuración de manera local en tu teléfono. Consulta el código de muestra y la documentación.