Adaptaciones automáticas de plataforma
Aprende más sobre la adaptabilidad de plataforma de Flutter.
Filosofía de adaptación
#En general, existen dos casos de adaptabilidad a la plataforma:
- Cosas que son comportamientos del entorno del sistema operativo (como la edición de texto y el desplazamiento) y que estarían 'mal' si ocurriera un comportamiento diferente.
- Cosas que convencionalmente se implementan en aplicaciones utilizando
los SDK de los fabricantes (como usar pestañas paralelas en iOS o
mostrar un
android.app.AlertDialogen Android).
Este artículo cubre principalmente las adaptaciones automáticas proporcionadas por Flutter en el caso 1 en Android e iOS.
Para el caso 2, Flutter incluye los medios para producir los efectos apropiados de las convenciones de la plataforma, pero no se adapta automáticamente cuando se necesitan elecciones de diseño de la aplicación. Para más detalles, consulta el issue #8410 y la definición del problema del widget adaptativo Material/Cupertino.
Para ver un ejemplo de una aplicación que utiliza diferentes estructuras de arquitectura de información en Android e iOS pero comparte el mismo código de contenido, consulta los ejemplos de código de platform_design.
Navegación de páginas
#Flutter proporciona los patrones de navegación que se ven en Android e iOS y también adapta automáticamente la animación de navegación a la plataforma actual.
Transiciones de navegación
#En Android, la transición predeterminada de Navigator.push()
está modelada según startActivity(),
que generalmente tiene una variante de animación de abajo hacia arriba.
En iOS:
- La API predeterminada
Navigator.push()produce una transición de estilo Show/Push de iOS que se anima de fin a inicio según la configuración RTL de la configuración regional. La página detrás de la nueva ruta también se desliza con efecto parallax en la misma dirección que en iOS. - Existe un estilo de transición independiente de abajo hacia arriba cuando
se realiza un push a una ruta de página donde
PageRoute.fullscreenDialoges verdadero. Esto representa la transición de estilo Present/Modal de iOS y se utiliza habitualmente en páginas modales a pantalla completa.

Transición de página de Android

Transición push de iOS

Transición present de iOS
Detalles de transición específicos de cada plataforma
#En Android, Flutter utiliza la animación ZoomPageTransitionsBuilder.
Cuando el usuario toca un elemento, la UI se acerca (zoom in) a una pantalla que muestra ese elemento.
Cuando el usuario toca para volver atrás, la UI se aleja (zoom out) a la pantalla anterior.
En iOS cuando se utiliza la transición de estilo push,
las barras de navegación integradas de Flutter CupertinoNavigationBar
y CupertinoSliverNavigationBar
animan automáticamente cada subcomponente a su
subcomponente correspondiente en la CupertinoNavigationBar o CupertinoSliverNavigationBar
de la página siguiente o anterior.

Android

Barra de navegación de iOS
Navegación hacia atrás
#En Android,
el botón de volver atrás del SO se envía, por defecto, a Flutter
y realiza un pop de la ruta superior del Navigator de WidgetsApp.
En iOS, se puede usar un gesto de deslizar desde el borde para hacer pop de la ruta superior.

Botón atrás de Android

Gesto de deslizar hacia atrás de iOS
Desplazamiento
#El desplazamiento es una parte importante del aspecto y la sensación de la plataforma, y Flutter ajusta automáticamente el comportamiento de desplazamiento para que coincida con la plataforma actual.
Simulación física
#Tanto Android como iOS tienen simulaciones físicas de desplazamiento complejas que son difíciles de describir verbalmente. En general, el elemento desplazable de iOS tiene más peso y fricción dinámica, pero Android tiene más fricción estática. Por lo tanto, iOS gana alta velocidad de forma más gradual, pero se detiene de manera menos abrupta y es más resbaladizo a velocidades bajas.

Comparación de impulso suave

Comparación de impulso medio

Comparación de impulso fuerte
Comportamiento de overscroll
#En Android, desplazarse más allá del borde de un elemento desplazable muestra un indicador de resplandor por overscroll (basado en el color del tema Material actual).
En iOS, desplazarse más allá del borde de un elemento desplazable hace overscroll con una resistencia creciente y regresa a su lugar.

Comparación de overscroll dinámico

Comparación de overscroll estático
Barras de desplazamiento
#En plataformas basadas en Material (como Android y web), las barras de desplazamiento suelen ser visibles durante el desplazamiento y pueden permanecer visibles según la plataforma y el tema.
En plataformas basadas en Cupertino (como iOS), las barras de desplazamiento son más minimalistas y generalmente solo aparecen brevemente mientras el usuario se desplaza activamente, desvaneciéndose cuando la interacción se detiene.
Esta diferencia refleja las convenciones visuales de cada plataforma y ayuda a mantener un aspecto y sensación nativos en todos los dispositivos.
Inercia
#En iOS, los impulsos (flings) repetidos en la misma dirección acumulan inercia y generan más velocidad con cada impulso sucesivo. No hay un comportamiento equivalente en Android.

Inercia de desplazamiento en iOS
Volver arriba
#En iOS, tocar la barra de estado del SO desplaza el controlador de desplazamiento principal hasta la posición superior. No hay un comportamiento equivalente en Android.

Toque en la barra de estado de iOS para volver arriba
Tipografía
#Al utilizar el paquete Material, la tipografía se ajusta automáticamente por defecto a la familia de fuentes adecuada para la plataforma. Android usa la fuente Roboto. iOS usa la fuente San Francisco.
Al utilizar el paquete Cupertino, el tema predeterminado usa la fuente San Francisco.
La licencia de la fuente San Francisco limita su uso únicamente a software que se ejecute en iOS, macOS o tvOS. Por lo tanto, se utiliza una fuente alternativa (fallback) cuando se ejecuta en Android si la plataforma se invalida en depuración (debug-overridden) a iOS o si se utiliza el tema Cupertino predeterminado.
Puedes optar por adaptar el estilo de texto de los widgets Material para que coincida con el estilo de texto predeterminado en iOS. Puedes ver ejemplos específicos de widgets en la sección Componentes de UI.

Roboto en Android

San Francisco en iOS
Iconografía
#Al utilizar el paquete Material, ciertos íconos muestran automáticamente gráficos diferentes según la plataforma. Por ejemplo, los tres puntos del botón de desbordamiento (overflow) son horizontales en iOS y verticales en Android. El botón de volver atrás es un chevron simple en iOS y tiene una flecha con tallo en Android.

Íconos en Android

Íconos en iOS
La librería Material también proporciona un conjunto de
íconos adaptativos para cada plataforma a través de Icons.adaptive.
Respuesta háptica
#Los paquetes Material y Cupertino activan automáticamente la respuesta háptica adecuada según la plataforma en determinados escenarios.
Por ejemplo, la selección de una palabra mediante la pulsación larga en un campo de texto activa una vibración tipo 'zumbido' en Android y no en iOS.
Desplazarse por los elementos de un selector (picker) en iOS activa un golpe de 'impacto ligero' y ninguna respuesta en Android.
Edición de texto
#Tanto los campos de entrada de texto de Material como los de Cupertino admiten la revisión ortográfica y se adaptan para utilizar la configuración de revisión ortográfica adecuada para la plataforma, así como el menú de revisión ortográfica y los colores de resaltado adecuados.
Flutter también realiza las siguientes adaptaciones al editar el contenido de los campos de texto para coincidir con la plataforma actual.
Navegación por gestos del teclado
#En Android, se pueden realizar deslices horizontales en la tecla espacio del teclado virtual para mover el cursor en los campos de texto de Material y Cupertino.
En dispositivos iOS con funciones 3D Touch, se podía realizar un gesto de presionar con fuerza y arrastrar en el teclado virtual para mover el cursor en 2D a través de un cursor flotante. Esto funciona tanto en los campos de texto de Material como en los de Cupertino.

Movimiento de cursor con tecla de espacio en Android

Movimiento de cursor arrastrando con 3D Touch en iOS
Barra de herramientas de selección de texto
#Con Material en Android, se muestra la barra de herramientas de selección de estilo Android cuando se realiza una selección de texto en un campo de texto.
Con Material en iOS o al usar Cupertino, se muestra la barra de herramientas de selección de estilo iOS cuando se realiza una selección de texto en un campo de texto.

Barra de herramientas de selección de texto de Android

Barra de herramientas de selección de texto de iOS
Gesto de toque único
#Con Material en Android, un toque único en un campo de texto coloca el cursor en la ubicación del toque.
Una selección de texto colapsada también muestra un controlador arrastrable para mover el cursor posteriormente.
Con Material en iOS o al usar Cupertino, un toque único en un campo de texto coloca el cursor en el borde más cercano de la palabra tocada.
Las selecciones de texto colapsadas no tienen controladores arrastrables en iOS.

Toque en Android

Toque en iOS
Gesto de pulsación larga
#Con Material en Android, una pulsación larga selecciona la palabra bajo la pulsación larga. La barra de herramientas de selección se muestra al soltar.
Con Material en iOS o al usar Cupertino, una pulsación larga coloca el cursor en la ubicación de la pulsación larga. La barra de herramientas de selección se muestra al soltar.

Pulsación larga en Android

Pulsación larga en iOS
Gesto de arrastre con pulsación larga
#Con Material en Android, arrastrar mientras se mantiene la pulsación larga expande las palabras seleccionadas.
Con Material en iOS o al usar Cupertino, arrastrar mientras se mantiene la pulsación larga mueve el cursor.

Arrastre con pulsación larga en Android

Arrastre con pulsación larga en iOS
Gesto de doble toque
#Tanto en Android como en iOS, un doble toque selecciona la palabra que recibe el doble toque y muestra la barra de herramientas de selección.

Doble toque en Android

Doble toque en iOS
Componentes de UI
#Esta sección incluye recomendaciones preliminares sobre cómo adaptar los widgets Material para ofrecer una experiencia natural y atractiva en iOS. Tus comentarios son bienvenidos en el issue #8427.
Widgets con constructores .adaptive()
#Varios widgets admiten constructores .adaptive().
La siguiente tabla enumera estos widgets.
Los constructores adaptativos sustituyen los componentes Cupertino correspondientes
cuando la aplicación se ejecuta en un dispositivo iOS.
Los widgets de la siguiente tabla se utilizan principalmente para la entrada, la selección y para mostrar información del sistema. Debido a que estos controles están estrechamente integrados con el sistema operativo, los usuarios están acostumbrados a reconocerlos y responder a ellos. Por lo tanto, te recomendamos seguir las convenciones de la plataforma.
| Widget Material | Widget Cupertino | Constructor adaptativo |
|---|---|---|
Switch
|
CupertinoSwitch
|
Switch.adaptive()
|
Slider
|
CupertinoSlider
|
Slider.adaptive()
|
CircularProgressIndicator
|
CupertinoActivityIndicator
|
CircularProgressIndicator.adaptive()
|
RefreshProgressIndicator
|
CupertinoActivityIndicator
|
RefreshIndicator.adaptive()
|
Checkbox
|
CupertinoCheckbox
|
Checkbox.adaptive()
|
Radio
|
CupertinoRadio
|
Radio.adaptive()
|
AlertDialog
|
CupertinoAlertDialog
|
AlertDialog.adaptive()
|
Barra de aplicaciones superior y barra de navegación
#Desde Android 12, la UI predeterminada para las barras de aplicaciones superiores sigue las pautas de diseño definidas en Material 3. En iOS, un componente equivalente llamado "Navigation Bars" está definido en las Human Interface Guidelines de Apple (HIG).

Top App Bar en Material 3

Navigation Bar en Human Interface Guidelines
Ciertas propiedades de las barras de aplicaciones en aplicaciones Flutter se deben adaptar,
como los íconos del sistema y las transiciones de página.
Estas ya se adaptan automáticamente al usar los
widgets Material AppBar y SliverAppBar.
También puedes personalizar aún más las propiedades de estos widgets para adaptarlos mejor a
los estilos de la plataforma iOS, como se muestra a continuación.
// Map the text theme to iOS styles
TextTheme cupertinoTextTheme = TextTheme(
headlineMedium: CupertinoThemeData()
.textTheme
.navLargeTitleTextStyle
// fixes a small bug with spacing
.copyWith(letterSpacing: -1.5),
titleLarge: CupertinoThemeData().textTheme.navTitleTextStyle)
...
// Use iOS text theme on iOS devices
ThemeData(
textTheme: Platform.isIOS ? cupertinoTextTheme : null,
...
)
...
// Modify AppBar properties
AppBar(
surfaceTintColor: Platform.isIOS ? Colors.transparent : null,
shadowColor: Platform.isIOS ? CupertinoColors.darkBackgroundGray : null,
scrolledUnderElevation: Platform.isIOS ? .1 : null,
toolbarHeight: Platform.isIOS ? 44 : null,
...
),
Sin embargo, dado que las barras de aplicaciones se muestran junto a otros contenidos en tu página, solo se recomienda adaptar el estilo mientras sea coherente con el resto de tu aplicación. Puedes ver muestras de código adicionales y una explicación más detallada en la discusión de GitHub sobre adaptaciones de barras de aplicaciones.
Barras de navegación inferiores
#Desde Android 12, la UI predeterminada para las barras de navegación inferiores sigue las pautas de diseño definidas en Material 3. En iOS, un componente equivalente llamado "Tab Bars" está definido en las Human Interface Guidelines de Apple (HIG).

Bottom Navigation Bar en Material 3

Tab Bar en Human Interface Guidelines
Dado que las barras de pestañas son persistentes en toda tu aplicación, deben coincidir con tu propia identidad de marca. Sin embargo, si eliges utilizar el estilo predeterminado de Material en Android, podrías considerar adaptarlo a las barras de pestañas predeterminadas de iOS.
Para implementar barras de navegación inferiores específicas de la plataforma,
puedes usar el widget NavigationBar de Flutter en Android
y el widget CupertinoTabBar en iOS.
A continuación se incluye un fragmento de código que puedes
adaptar para mostrar barras de navegación específicas de la plataforma.
final Map<String, Icon> _navigationItems = {
'Menu': Platform.isIOS ? Icon(CupertinoIcons.house_fill) : Icon(Icons.home),
'Order': Icon(Icons.adaptive.share),
};
...
Scaffold(
body: _currentWidget,
bottomNavigationBar: Platform.isIOS
? CupertinoTabBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() => _currentIndex = index);
_loadScreen();
},
items: _navigationItems.entries
.map<BottomNavigationBarItem>(
(entry) => BottomNavigationBarItem(
icon: entry.value,
label: entry.key,
))
.toList(),
)
: NavigationBar(
selectedIndex: _currentIndex,
onDestinationSelected: (index) {
setState(() => _currentIndex = index);
_loadScreen();
},
destinations: _navigationItems.entries
.map<Widget>((entry) => NavigationDestination(
icon: entry.value,
label: entry.key,
))
.toList(),
));
Campos de texto
#Desde Android 12, los campos de texto siguen las pautas de diseño de Material 3 (M3). En iOS, las Human Interface Guidelines (HIG) de Apple definen un componente equivalente.

Text Field en Material 3

Text Field en HIG
Dado que los campos de texto requieren la entrada del usuario, su diseño debe seguir las convenciones de la plataforma.
Para implementar un TextField específico de la plataforma
en Flutter, puedes adaptar el estilo del
TextField de Material.
Widget _createAdaptiveTextField() {
final _border = OutlineInputBorder(
borderSide: BorderSide(color: CupertinoColors.lightBackgroundGray),
);
final iOSDecoration = InputDecoration(
border: _border,
enabledBorder: _border,
focusedBorder: _border,
filled: true,
fillColor: CupertinoColors.white,
hoverColor: CupertinoColors.white,
contentPadding: EdgeInsets.fromLTRB(10, 0, 0, 0),
);
return Platform.isIOS
? SizedBox(
height: 36.0,
child: TextField(
decoration: iOSDecoration,
),
)
: TextField();
}
Para aprender más sobre la adaptación de campos de texto, echa un vistazo a la discusión de GitHub sobre campos de texto. Puedes dejar comentarios o hacer preguntas en la discusión.
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.