Node.js

Crear una aplicación Android básica

Cree MainActivity.kt

Abrir MainActivity.kt y añada el siguiente contenido. Esto corresponde a una Actividad mínima.

package com.vonage.verify2.test

import android.os.Bundle
import androidx.activity.ComponentActivity

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}

A continuación, defina la constante de la URL backend mediante BuildConfig:

private const val BACKEND_URL = BuildConfig.BACKEND_URL

Creación de la interfaz de usuario con Jetpack Compose

En esta sección, construiremos el interfaz de usuario para nuestro flujo de verificación. Hay aún no hay red porque el objetivo es crear una interfaz de usuario limpia que más tarde podamos conectar a los puntos finales del backend.

La nueva MainActivity tendrá este aspecto:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { VerifyApp() }
    }
}

Implementemos VerifyApp()

@Composable
fun VerifyApp() {
    MaterialTheme {
        Surface(modifier = Modifier.fillMaxSize()) {
            VerificationScreen()
        }
    }
}

Nuestra interfaz de usuario tiene un pequeño número de "momentos" (pantallas) que dependen del paso de verificación actual:

  1. Introduzca el número de teléfono
  2. Cargando
  3. Introducir código SMS (fallback)
  4. Verificado
  5. Error

Jetpack Compose hace esto fácil si modelamos la pantalla como un máquina de estados.

Crear una máquina de estados de interfaz de usuario

Definimos una clase sellada para representar todos los posibles estados de la interfaz de usuario:

private sealed class VerifyUiState {
    data object EnterPhone : VerifyUiState()
    data object Loading : VerifyUiState()
    data class EnterSms(val requestId: String) : VerifyUiState()
    data class Verified(val method: String) : VerifyUiState()
    data class Error(val message: String) : VerifyUiState()
}

Aunque todavía no estamos integrando con el backend, ya incluimos un requestId en el estado SMS porque se necesitará más adelante.

Crear la pantalla y su estado de interfaz de usuario local

En VerificationScreen() almacenamos las entradas del usuario y el estado actual de la interfaz de usuario con remember { mutableStateOf(...) }:

var phone by remember { mutableStateOf(DEFAULT_PHONE) }
var smsCode by remember { mutableStateOf("") }
var uiState by remember { mutableStateOf<VerifyUiState>(VerifyUiState.EnterPhone) }
var statusMessage by remember { mutableStateOf("") }

Construir el diseño con una columna simple

Creamos un diseño centrado utilizando Column, Spacery Modifier:

Column(
    modifier = Modifier.fillMaxSize().padding(16.dp),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) { ... }

En su interior mostramos:

  • Un título
  • Entrada de teléfono
  • Entrada SMS opcional
  • Botones basados en el estado actual de la interfaz de usuario
  • Un mensaje de estado en la parte inferior

Entrada de teléfono

OutlinedTextField(
    value = phone,
    onValueChange = { phone = it },
    enabled = uiState !is VerifyUiState.Loading,
    label = { Text("Phone number") },
    placeholder = { Text("+34600000000") },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone),
    modifier = Modifier.fillMaxWidth()
)

Notas:

  • Desactivamos la entrada durante la carga para evitar el doble envío.
  • Utilizamos KeyboardType.Phone para mostrar un teclado compatible con el teléfono.
Verify and Silent Auth Tutorial

Entrada SMS

La entrada de SMS se implementará con un renderizado condicional. Compose hace que la interfaz de usuario condicional sea muy sencilla.

Mostramos la entrada SMS sólo si estamos en EnterSms:

val requestIdForSms = (uiState as? VerifyUiState.EnterSms)?.requestId
if (requestIdForSms != null) {
    OutlinedTextField(
        value = smsCode,
        onValueChange = { smsCode = it },
        enabled = uiState !is VerifyUiState.Loading,
        label = { Text("SMS code") },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
        modifier = Modifier.fillMaxWidth()
    )
}

Más tarde, cuando nos integramos con el backend, este requestId procederá de /verification.

Mostrar el botón de acción correcto en función del estado de la interfaz de usuario

Utilizamos when (uiState):

  • Cargando → mostrar un spinner
  • IntroTeléfono / Error → mostrar "Iniciar verificación".
  • EnterSms → mostrar "Enviar código"
  • Verificado → mostrar éxito + "Verificar otro número".

Este es el patrón central de Compose utilizado en aplicaciones reales: UI = function(state).

Verify and Silent Auth Tutorial