El problema
Una app Flutter que se publica en móviles, tabletas y escritorio necesita algo más que una columna flexible. Una pantalla que se lee bien con 390 píxeles lógicos de ancho pide una tarjeta centrada a 700 y una barra lateral a 1200. Flutter da las medidas, pero no una estructura donde aplicarlas.
Así que las comprobaciones se dispersan. Aquí un MediaQuery.of(context).size.width > 600, allí un LayoutBuilder, y tres widgets más abajo un ternario dentro de un Padding. Cada una parece razonable por separado; juntas forman una política de diseño que no está escrita en ningún sitio.
Los problemas más comunes son:
- Valores de breakpoint duplicados en decenas de widgets, que van divergiendo a medida que cambia el diseño
LayoutBuilderdevolviendo las restricciones del padre cuando lo que hacía falta era el dispositivo- Diseños que saltan a la variante de tableta en cuanto se gira el móvil a horizontal
- Árboles de widgets donde la lógica adaptativa es imposible de ver sin leer cada hijo
Cómo lo resuelve flutter_adaptive_layout
AdaptiveLayout recibe un builder por tamaño de pantalla y un child. Mide el dispositivo con MediaQuery, lo traduce a un ScreenSize y construye solo la variante que corresponde, con el child creado una sola vez y entregado al builder elegido.
AdaptiveLayout(
smallBuilder: (context, child) => child!,
mediumBuilder: (context, child) => Center(child: child),
largeBuilder: (context, child) => Row(
children: [const Sidebar(), Expanded(child: child!)],
),
child: const MyHomePage(),
)
La decisión adaptativa vive ahora en un único widget, en la raíz del subárbol que gobierna, escrita como tres disposiciones en lugar de una cadena de condiciones.


Qué ofrece
- Disposiciones por tamaño de pantalla —
smallBuilder,mediumBuilderylargeBuilder, todos opcionales; si falta uno se dibuja elchild, así que puedes describir solo los tamaños que te importan - Breakpoints bajo tu control — 400 y 600 píxeles lógicos por defecto, redefinibles por widget o para toda la app
- El child se construye una vez — al cambiar de disposición el contenido se envuelve, no se reconstruye desde cero
- Estable ante la rotación — la clasificación lee
MediaQuery.of(context).size.shortestSide, así que un móvil sigue siendo pantalla pequeña en horizontal - Lógica de clasificación conectable — implementa
ScreenSizeQualifierpara clasificar por ancho, plataforma, estado de la bisagra o como lo haga tu sistema de diseño - Sin dependencias — Flutter puro sobre
MediaQuery, funciona en iOS, Android, web, macOS, Windows y Linux
Cómo se decide el tamaño de pantalla
El BreakpointsQualifier por defecto compara el lado más corto con dos breakpoints, de forma inclusiva: un valor igual al breakpoint pertenece a la categoría menor.
| Tamaño de pantalla | Condición | Rango por defecto | Dispositivo típico |
|---|---|---|---|
ScreenSize.small | shortestSide <= smallBreakpoint | 0–400 píxeles lógicos | Móviles |
ScreenSize.medium | shortestSide <= mediumBreakpoint | 401–600 píxeles lógicos | Tabletas pequeñas |
ScreenSize.large | por encima de mediumBreakpoint | 601+ píxeles lógicos | Tabletas grandes, escritorio |
Los breakpoints se resuelven en un orden fijo y gana el primer valor definido: los argumentos de BreakpointsQualifier, después el BreakpointsSetting ancestro más cercano y, por último, los 400 y 600 integrados.
Casos de uso reales
Del móvil a la tableta
Una app que empezó en móviles puede conservar todas sus pantallas y añadir un largeBuilder donde una disposición ancha compense. Las pantallas sin builder para ese tamaño dibujan el child tal cual, así que la migración va pantalla a pantalla en vez de toda de golpe.
Navegación maestro-detalle
Una lista que en el móvil abre el detalle como una ruta nueva puede mostrar lista y detalle lado a lado en una tableta. Las dos variantes se declaran juntas en un mismo widget, de modo que la diferencia se revisa en el propio diff.
Sistemas de diseño con sus propios breakpoints
Envuelve MaterialApp en BreakpointsSetting una vez y todos los AdaptiveLayout del árbol tomarán los números del sistema de diseño. Cambiarlos más adelante es editar una línea, no buscar por todo el proyecto.
Ventanas en web y escritorio
En web y escritorio se mide el tamaño de la ventana, así que la disposición responde mientras el usuario la redimensiona: el mismo código que atiende a una tableta atiende a un navegador reducido.
Cómo empezar
Instala el paquete:
flutter pub add flutter_adaptive_layout
Requiere Dart >=2.18.5 <4.0.0 y Flutter 1.17+.
Impórtalo y envuelve el widget cuya disposición deba adaptarse:
import 'package:flutter_adaptive_layout/flutter_adaptive_layout.dart';
AdaptiveLayout(
largeBuilder: (context, child) => Center(
child: SizedBox(width: 600, child: child),
),
child: const ArticleView(), // en pantallas pequeñas y medianas, tal cual
)
Para clasificar las pantallas de otra forma, implementa ScreenSizeQualifier y pásalo como qualifier:
class WidthQualifier extends ScreenSizeQualifier {
@override
ScreenSize qualify(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width < 600) return ScreenSize.small;
if (width < 1024) return ScreenSize.medium;
return ScreenSize.large;
}
}
qualify se ejecuta en cada build, así que debe ser barato y libre de efectos secundarios.
Hay una app completa y ejecutable en el directorio example.