Plegables: posturas, bisagra y continuidad
Un plegable no es una pantalla grande ni una pequeña, sino un dispositivo cuya geometría cambia mientras el usuario lo sostiene y cuya superficie puede estar partida por un obstáculo físico. Esta lección modela la postura como estado observable, explica cómo se lee la característica de plegado con su estado, su orientación y su capacidad de separación, desarrolla el modo mesa y el modo libro como oportunidades de diseño y no como excepciones, y aborda el problema que hunde a la mayoría de las aplicaciones: mantener la sesión intacta al plegar y desplegar.
Los plegables obligan a añadir una dimensión que ninguna otra clase de dispositivo exige. Con una tablet basta con saber cuánto espacio hay; con un plegable hace falta saber además qué forma tiene ese espacio y en qué ángulo está, porque el aparato puede estar completamente abierto, completamente cerrado o detenido a medio camino sobre una mesa, y porque en ese estado intermedio la superficie deja de ser un plano continuo para convertirse en dos regiones separadas por una arista física. A eso se suma la transición: plegar y desplegar es un cambio de configuración que ocurre en mitad de una tarea, con el vídeo reproduciéndose, el formulario a medio rellenar y el mapa centrado en un punto. La calidad percibida de una aplicación en un plegable se decide casi por completo en ese medio segundo. Esta lección trata la postura como un estado de primera clase, la bisagra como una restricción de colocación y la continuidad como un requisito funcional.
- Modelar la postura del dispositivo como un estado observable con su fuente de verdad.
- Interpretar el estado, la orientación y la capacidad de separación de la característica de plegado.
- Diseñar para el modo mesa y el modo libro sin tratarlos como casos excepcionales.
- Garantizar la continuidad de la sesión a través de los cambios de postura.
La postura como estado observable
La información sobre el plegado no llega por consulta puntual sino por flujo: el sistema publica un objeto que describe la disposición de la ventana cada vez que cambia, y la aplicación se suscribe. Ese objeto contiene una lista de características de la pantalla, de las cuales la relevante aquí es la característica de plegado, que aparece únicamente cuando existe una y cuando afecta a la ventana de tu aplicación.
Esa característica tiene tres atributos que hay que leer juntos, porque por separado no dicen nada útil. El estado distingue entre plano y medio abierto: plano significa que la superficie es continua a efectos prácticos, medio abierto que el aparato está detenido en un ángulo intermedio. La orientación indica si el pliegue recorre la pantalla horizontal o verticalmente, y determina si el espacio queda partido en arriba y abajo o en izquierda y derecha. Y la capacidad de separación es una síntesis que el propio sistema calcula y que responde a la única pregunta que de verdad importa para el diseño: si esa característica parte la superficie en dos áreas lógicas que deben tratarse por separado.
class ObservadorDePostura(private val actividad: ComponentActivity) {
val postura = WindowInfoTracker.getOrCreate(actividad)
.windowLayoutInfo(actividad)
.map { info ->
val plegado = info.displayFeatures.filterIsInstance<FoldingFeature>().firstOrNull()
when {
plegado == null -> Postura.Plana
!plegado.isSeparating -> Postura.Plana
plegado.orientation == FoldingFeature.Orientation.HORIZONTAL -> Postura.Mesa(plegado.bounds)
else -> Postura.Libro(plegado.bounds)
}
}
}
Dos advertencias sobre el consumo de ese flujo. La primera es que debe recogerse de forma consciente del ciclo de vida, para no seguir procesando actualizaciones con la actividad en segundo plano; el patrón de recolección que se detiene y reanuda con el estado de la actividad es el correcto y no hay ninguna razón para desviarse de él. La segunda es que el flujo describe la disposición de tu ventana, no la del aparato: si tu aplicación ocupa solo una mitad de la pantalla en multiventana y el pliegue cae fuera de ella, no recibirás característica alguna, y eso es exactamente lo que se quiere.
La modelación importa más que la lectura. Convertir tres atributos crudos en un tipo cerrado con tres casos hace que el resto de la aplicación razone sobre conceptos de diseño —mesa, libro, plano— en lugar de sobre banderas, y que la exhaustividad de las decisiones sea comprobable por el compilador. Es el mismo movimiento de cuantización que se hizo con el tamaño, aplicado a otra dimensión.
La característica de plegado expone también unos límites rectangulares. En los plegables con bisagra visible ese rectángulo tiene grosor real y ocupa píxeles que no se ven o se ven deformados; en los de pliegue continuo puede ser una línea de grosor cero, sin obstáculo físico pero con un doblez perceptible. En ambos casos, lo que hay que evitar es que un control interactivo o una línea de texto caigan justo encima, y por eso la posición se lee del sistema y jamás se codifica a mano.
La bisagra como restricción de colocación
Colocar contenido a caballo de un pliegue produce tres problemas distintos que conviene separar. Uno visual: un texto o una imagen partidos por una arista se leen mal o no se leen. Uno de interacción: un botón situado sobre la bisagra es difícil de pulsar y su respuesta táctil es incoherente. Y uno de comprensión: cuando el aparato está medio abierto, las dos mitades apuntan en direcciones distintas y el usuario percibe dos superficies, no una, de modo que un elemento partido se lee como dos elementos.
La respuesta más simple es tratar la banda del pliegue como una zona prohibida y repartir el contenido a sus lados. En Compose esto encaja de forma natural con los patrones canónicos: la banda se convierte en la separación entre paneles, y cada panel ocupa una mitad. Las estructuras adaptativas del nivel anterior ya lo hacen por su cuenta, porque la directiva que las gobierna incorpora la característica de plegado y decide en consecuencia; ese es uno de los argumentos más fuertes para usarlas en lugar de construir dos columnas a mano.
flowchart TD A[Flujo de informacion de disposicion] --> B[Hay caracteristica de plegado] B --> C[No hay o no separa] B --> D[Separa la superficie] C --> E[Postura plana con superficie continua] D --> F[Orientacion horizontal] D --> G[Orientacion vertical] F --> H[Modo mesa con contenido arriba y control abajo] G --> I[Modo libro con dos paneles] E --> J[Directiva sin separacion] H --> K[Directiva con separacion horizontal] I --> L[Directiva con separacion vertical] style D fill:#f9e2af,color:#11111b
// La banda del pliegue se convierte en separacion, nunca en una fraccion inventada
@Composable
fun ContenidoConPliegue(postura: Postura, contenido: @Composable (PaddingValues) -> Unit) {
val densidad = LocalDensity.current
val separacion = when (postura) {
is Postura.Mesa -> with(densidad) { postura.limites.height().toDp() }
is Postura.Libro -> with(densidad) { postura.limites.width().toDp() }
Postura.Plana -> 0.dp
}
contenido(PaddingValues(vertical = separacion / 2))
}
Cuando la disposición no se presta a dos paneles, la alternativa es reservar la banda como margen. La tentación de calcular ese margen como una fracción fija de la altura debe resistirse: la posición del pliegue no está centrada en todos los dispositivos, cambia con el modelo y puede cambiar con la orientación. Se lee de los límites que publica el sistema, se traduce a unidades independientes de densidad y se aplica como separación.
Mesa y libro como oportunidades de diseño
El modo mesa aparece cuando el aparato está medio abierto con el pliegue horizontal, apoyado sobre una superficie. Es la postura más interesante porque no es una versión degradada de nada: es una configuración que ningún otro dispositivo ofrece, con una mitad superior orientada hacia la vista y una mitad inferior orientada hacia las manos. Esa asimetría tiene una lectura de diseño inmediata y muy productiva: arriba lo que se mira, abajo lo que se toca.
De ahí salen aplicaciones evidentes. Un reproductor de vídeo pone la imagen arriba y los controles con la lista de reproducción abajo, y logra sin trípode lo que en un teléfono plano exige sostenerlo. Una cámara sitúa el visor arriba y los ajustes abajo, y permite el autorretrato con manos libres. Una videollamada coloca a los interlocutores arriba y el teclado o los controles abajo. Un mapa muestra el trazado arriba y la lista de indicaciones abajo. En todos los casos, el cambio de disposición no añade funciones: reorganiza las existentes según el eje mirar y tocar.
Conviene notar que ninguna de esas aplicaciones exige contenido nuevo ni pantallas nuevas, y ese es el argumento decisivo para abordar el modo mesa antes que cualquier otra mejora de plegables: el trabajo consiste en redistribuir piezas que ya existen a lo largo de un eje que el usuario acaba de crear con las manos.
El modo libro aparece con el pliegue vertical y el aparato medio abierto, sostenido como un volumen impreso. Su lectura es distinta y menos espectacular pero igual de útil: dos páginas de igual rango. Encaja con lectores, con galerías de dos imágenes, con documentos a doble página y con cualquier lista y detalle donde ambos lados tengan peso comparable.
Mesa
Pliegue horizontal, mitad superior para ver y mitad inferior para manipular. Manos libres sin accesorios. Vídeo, cámara, llamadas y navegación.
Libro
Pliegue vertical, dos superficies de igual rango. Lectura, comparación y edición con referencia al lado.
Hay una tercera postura que suele olvidarse y que da más valor por menos trabajo que las dos anteriores: la pantalla exterior con el aparato cerrado. En muchos plegables es una superficie plenamente funcional, y a menudo con proporciones inusuales que rompen suposiciones de diseño. Además, el sistema ofrece la posibilidad de mover una sesión a esa pantalla exterior, lo que habilita casos como el autorretrato con la cámara principal usando la pantalla externa como visor. Requiere pedir el cambio de área de visualización y estar preparado para que el contenido aterrice en un rectángulo muy distinto.
Continuidad: el medio segundo que decide todo
Plegar o desplegar es un cambio de configuración, y por defecto el sistema destruye y recrea la actividad. Todo lo que no esté preparado desaparece: la posición del desplazamiento, el texto a medio escribir, el fotograma del vídeo, la selección, el estado del formulario, la posición de la cámara del mapa. El usuario no interpreta eso como una limitación del hardware sino como un fallo de la aplicación, y con razón.
La solución tiene tres capas y conviene aplicarlas en orden. La primera es el estado de larga vida, que pertenece a un contenedor que sobrevive a la recreación —el modelo de vista— y que debe albergar todo lo que sea datos, selección y navegación. La segunda es el estado efímero de la interfaz, que se conserva con los mecanismos de guardado de la composición y que cubre desplazamientos, expansiones y campos de texto. La tercera son los recursos con posición propia, como un reproductor multimedia o una sesión de cámara, que no se guardan copiando un valor sino gestionando su ciclo de vida por encima del de la actividad y restaurando la posición exacta.
// Lo que debe sobrevivir a plegar y desplegar, por capas
class ModeloDeVista : ViewModel() {
val seleccionado = MutableStateFlow<Long?>(null) // capa uno
val posicionMedia = MutableStateFlow(0L) // capa tres, valor a restaurar
}
@Composable
fun Contenido(modelo: ModeloDeVista) {
val estadoLista = rememberLazyListState() // capa dos
var borrador by rememberSaveable { mutableStateOf("") }
}
Hay una cuarta capa que no es de estado sino de percepción y que decide buena parte de la calidad percibida: la transición visual. Aunque el estado sobreviva íntegro, un cambio brusco de disposición se lee como un parpadeo y hace dudar al usuario de si algo se ha perdido. Animar el paso de una columna a dos, conservar la posición del elemento seleccionado durante el movimiento y evitar el fotograma en blanco cuestan poco cuando se usan las estructuras adaptativas —que ya traen las animaciones calibradas— y muchísimo cuando se construyen a mano.
Queda una decisión de diseño que se plantea siempre y que conviene resolver con criterio: si conviene declarar en el manifiesto que la actividad gestiona por su cuenta los cambios de tamaño y de orientación para evitar la recreación. La respuesta honesta es que esa declaración resuelve el síntoma y esconde el problema. Una aplicación que solo funciona porque nunca se recrea sigue perdiendo el estado cuando el sistema mata el proceso por presión de memoria, que es un escenario mucho más frecuente en tablets con varias aplicaciones abiertas. Manejar el cambio puede ser legítimo por rendimiento en casos concretos, pero nunca sustituye a la gestión correcta del estado.
La mayoría de los equipos prueban plegado y desplegado como dos estados estáticos y ambos funcionan. Los defectos viven en el camino: el fotograma en negro, el salto de desplazamiento, el diálogo que se cierra solo, la reproducción que se reinicia, el teclado que desaparece llevándose el texto. La prueba correcta consiste en plegar y desplegar repetidamente durante una tarea en curso, no antes ni después de ella.
Hay un salto conceptual en los plegables que conviene nombrar porque separa a las aplicaciones que meramente sobreviven de las que aprovechan el aparato, y porque su lógica se generaliza a todo el diseño adaptativo. La lectura mínima de un plegable es geométrica: el espacio cambia de tamaño y de forma, y la interfaz debe reacomodarse sin romperse. Es necesaria y es insuficiente. La lectura profunda es que el usuario, al detener el aparato en un ángulo intermedio y apoyarlo sobre una mesa, ha realizado un acto físico deliberado que ninguna otra clase de dispositivo permite, y ese acto comunica una intención con una precisión que ninguna telemetría alcanza. Nadie deja un plegable medio abierto por accidente. Quien lo hace está diciendo, sin tocar la pantalla, que quiere mirar sin sostener y manipular sin tapar; está construyendo con sus manos una configuración de trabajo. Esto convierte la postura en algo categóricamente distinto de una anchura en puntos: la anchura es una circunstancia que le ocurre a la aplicación, mientras que la postura es un mensaje que el usuario le envía. Y una vez que se acepta esa lectura, la pregunta de diseño cambia de naturaleza. Deja de ser cómo reacomodo mis elementos en una superficie partida, que es un problema de layout con solución mecánica, y pasa a ser qué está intentando hacer alguien que ha colocado su dispositivo así, que es un problema de producto con solución observable en el uso real. Las respuestas más citadas —el vídeo con controles abajo, la cámara con visor arriba, la videollamada manos libres— no se dedujeron de la geometría; se dedujeron de mirar qué hace la gente con las manos cuando el aparato está en esa postura. Y aquí llega la generalización que justifica la digresión: este mismo razonamiento aplica hacia atrás a todo el nivel. Conectar un teclado a una tablet es un mensaje sobre la intención de escribir en serio. Arrastrar una ventana hasta ocupar media pantalla es un mensaje sobre la intención de comparar. Girar un teléfono a horizontal es un mensaje sobre la intención de ver. Cada cambio de configuración que el usuario provoca deliberadamente contiene información sobre lo que quiere hacer a continuación, y la mayoría de las aplicaciones la desperdician por completo, tratándola como un evento de relayout que hay que absorber sin romperse. Adaptarse es no romperse; responder es entender lo que se te está diciendo. La distancia entre ambas cosas es la que separa una aplicación correcta de una que la gente recomienda.
- Modela la postura como un tipo cerrado con los casos plana, mesa y libro a partir del flujo de disposición, y hazlo descender por tu árbol como parámetro.
- Localiza en tu pantalla principal cualquier contenido que quede a caballo del pliegue en modo libro y repártelo a los lados usando los límites que publica el sistema.
- Diseña una disposición de modo mesa para tu caso de uso más visual aplicando el eje mirar arriba y tocar abajo. Si no encuentras ninguno, argumenta por qué en cinco líneas.
- Ejecuta una tarea larga —reproducir, rellenar, desplazar— y pliega y despliega tres veces en mitad de ella. Anota todo lo que se pierda y asígnalo a una de las tres capas de estado.
- Comprueba qué ocurre en la pantalla exterior con el aparato cerrado y corrige la primera suposición de proporción que se rompa.