Construir un diseño en Flutter
Aprende cómo construir un diseño en Flutter.
Este tutorial explica cómo diseñar y construir diseños en Flutter.
Si utilizas el código de ejemplo proporcionado, puedes construir la siguiente aplicación.
La aplicación terminada.
Foto de Dino Reichmuth en Unsplash. Texto de Switzerland Tourism.
Para obtener una mejor visión general del mecanismo de diseño, comienza con el enfoque de diseño de Flutter.
Diagramar el diseño
#En esta sección, considera qué tipo de experiencia de usuario quieres para los usuarios de tu aplicación.
Considera cómo posicionar los componentes de tu interfaz de usuario. Un diseño consiste en el resultado final total de estos posicionamientos. Considera planificar tu diseño para acelerar tu codificación. Usar pistas visuales para saber dónde va algo en la pantalla puede ser de gran ayuda.
Usa el método que prefieras, como una herramienta de diseño de interfaz o un lápiz y una hoja de papel. Descubre dónde quieres colocar los elementos en tu pantalla antes de escribir código. Es la versión en programación del proverbio: "Mide dos veces, corta una vez".
Haz estas preguntas para desglosar el diseño en sus elementos básicos.
- ¿Puedes identificar las filas y columnas?
- ¿El diseño incluye una cuadrícula (grid)?
- ¿Hay elementos superpuestos?
- ¿La interfaz de usuario necesita pestañas (tabs)?
- ¿Qué necesitas alinear, rellenar o bordear?
Identifica los elementos más grandes. En este ejemplo, organizas la imagen, el título, los botones y la descripción en una columna.
Elementos principales en el diseño: imagen, fila, fila y bloque de texto
Diagrama cada fila.
La fila 1, la sección Title, tiene tres hijos: una columna de texto, un icono de estrella y un número. Su primer hijo, la columna, contiene dos líneas de texto. Esa primera columna podría necesitar más espacio.
Sección de título con bloques de texto y un icono
La fila 2, la sección Button, tiene tres hijos: cada hijo contiene una columna que a su vez contiene un icono y texto.
La sección de botones con tres botones etiquetados
Después de diagramar el diseño, considera cómo lo codificarías.
¿Escribirías todo el código en una sola clase? ¿O crearías una clase para cada parte del diseño?
Para seguir las mejores prácticas de Flutter, crea una clase, o Widget,
para contener cada parte de tu diseño.
Cuando Flutter necesita volver a renderizar parte de una interfaz de usuario,
actualiza la parte más pequeña que cambia.
Es por esto que Flutter hace que "todo sea un widget".
Si solo cambia el texto en un widget Text, Flutter redibuja únicamente ese texto.
Flutter cambia la menor cantidad posible de la interfaz de usuario en respuesta a la entrada del usuario.
Para este tutorial, escribe cada elemento que hayas identificado como su propio widget.
Crear el código base de la aplicación
#En esta sección, bosqueja el código básico de la aplicación Flutter para comenzar tu aplicación.
-
Reemplaza el contenido de
lib/main.dartcon el siguiente código. Esta aplicación usa un parámetro para el título de la aplicación y el título mostrado en laappBarde la aplicación. Esta decisión simplifica el código.dartimport 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { const String appTitle = 'Flutter layout demo'; return MaterialApp( title: appTitle, home: Scaffold( appBar: AppBar(title: const Text(appTitle)), body: const Center( child: Text('Hello World'), ), ), ); } }
Agregar la sección de Título
#En esta sección, crea un widget TitleSection que se asemeje a
la siguiente disposición.
La sección de título como boceto y prototipo de interfaz de usuario
Agregar el Widget TitleSection
#
Agrega el siguiente código después de la clase MyApp.
class TitleSection extends StatelessWidget {
const TitleSection({super.key, required this.name, required this.location});
final String name;
final String location;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*2*/
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Text(location, style: TextStyle(color: Colors.grey[500])),
],
),
),
/*3*/
Icon(Icons.star, color: Colors.red[500]),
const Text('41'),
],
),
);
}
}
- Para usar todo el espacio libre restante en la fila, usa el widget
Expandedpara estirar el widgetColumn. Para colocar la columna al comienzo de la fila, establece la propiedadcrossAxisAlignmentenCrossAxisAlignment.start. - Para agregar espacio entre las filas de texto, coloca esas filas en un widget
Padding. - La fila de título termina con un icono de estrella roja y el texto
41. Toda la fila queda dentro de un widgetPaddingy aplica un relleno en cada borde de 32 píxeles.
Cambiar el cuerpo de la aplicación a una vista desplazable
#En la propiedad body, reemplaza el widget Center por un widget
SingleChildScrollView.
Dentro del widget SingleChildScrollView,
reemplaza el widget Text por un widget
Column.
body: const Center(
child: Text('Hello World'),
body: const SingleChildScrollView(
child: Column(
children: [
Estas actualizaciones de código cambian la aplicación de las siguientes maneras.
- Un widget
SingleChildScrollViewse puede desplazar. Esto permite mostrar elementos que no caben en la pantalla actual. - Un widget
Columnmuestra cualquier elemento dentro de su propiedadchildrenen el orden indicado. El primer elemento indicado en la listachildrense muestra en la parte superior de la lista. Los elementos en la listachildrense muestran en orden de arreglo en la pantalla de arriba a abajo.
Actualizar la aplicación para mostrar la sección de título
#Agrega el widget TitleSection como el primer elemento de la lista children.
Esto lo coloca en la parte superior de la pantalla.
Pasa el nombre y la ubicación proporcionados al constructor de TitleSection.
children: [
TitleSection(
name: 'Oeschinen Lake Campground',
location: 'Kandersteg, Switzerland',
),
],
Agregar la sección de Botones
#En esta sección, agrega los botones que añadirán funcionalidad a tu aplicación.
La sección Button contiene tres columnas que usan el mismo diseño: un icono sobre una fila de texto.
La sección de botones como boceto y prototipo de interfaz de usuario
Planifica distribuir estas columnas en una fila para que cada una ocupe la misma cantidad de espacio. Pinta todo el texto e iconos con el color primario.
Agregar el widget ButtonSection
#
Agrega el siguiente código después del widget TitleSection para contener el código
para construir la fila de botones.
class ButtonSection extends StatelessWidget {
const ButtonSection({super.key});
@override
Widget build(BuildContext context) {
final Color color = Theme.of(context).primaryColor;
// ···
}
}
Crear un widget para hacer botones
#Como el código para cada columna podría usar la misma sintaxis,
crea un Widget llamado ButtonWithText.
El constructor del Widget acepta un color, datos de ícono y una etiqueta para el botón.
Usando estos valores, el Widget construye una Column con un Icon
y un Widget de
Text estilizado como sus hijos.
Para ayudar a separar estos hijos, un Widget Padding — el Widget Text
se envuelve con un Widget Padding.
Agrega el siguiente código después de la clase ButtonSection.
class ButtonSection extends StatelessWidget {
const ButtonSection({super.key});
// ···
}
class ButtonWithText extends StatelessWidget {
const ButtonWithText({
super.key,
required this.color,
required this.icon,
required this.label,
});
final Color color;
final IconData icon;
final String label;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
}
Posicionar los botones con un widget Row
#
Agrega el siguiente código dentro del widget ButtonSection.
- Agrega tres instancias del widget
ButtonWithText, una para cada botón. - Pasa el color,
Icony texto para ese botón específico. - Alinea las columnas a lo largo del eje principal con el
valor
MainAxisAlignment.spaceEvenly. El eje principal para un widgetRowes horizontal y el eje principal para un widgetColumnes vertical. Este valor, entonces, le dice a Flutter que organice el espacio libre en cantidades iguales antes, entre y después de cada columna a lo largo delRow.
class ButtonSection extends StatelessWidget {
const ButtonSection({super.key});
@override
Widget build(BuildContext context) {
final Color color = Theme.of(context).primaryColor;
return SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ButtonWithText(color: color, icon: Icons.call, label: 'CALL'),
ButtonWithText(color: color, icon: Icons.near_me, label: 'ROUTE'),
ButtonWithText(color: color, icon: Icons.share, label: 'SHARE'),
],
),
);
}
}
class ButtonWithText extends StatelessWidget {
const ButtonWithText({
super.key,
required this.color,
required this.icon,
required this.label,
});
final Color color;
final IconData icon;
final String label;
@override
Widget build(BuildContext context) {
return Column(
// ···
);
}
}
Actualizar la aplicación para mostrar la sección de botones
#Agrega la sección de botones a la lista children.
TitleSection(
name: 'Oeschinen Lake Campground',
location: 'Kandersteg, Switzerland',
),
ButtonSection(),
],
Agregar la sección de Texto
#En esta sección, agrega la descripción de texto a esta aplicación.
El bloque de texto como boceto y prototipo de interfaz de usuario
Agregar el widget TextSection
#
Agrega el siguiente código como un widget separado después del widget ButtonSection.
class TextSection extends StatelessWidget {
const TextSection({super.key, required this.description});
final String description;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(32),
child: Text(description, softWrap: true),
);
}
}
Al establecer softWrap
en true, las líneas de texto llenan el ancho de la columna antes
de ajustarse en el límite de una palabra.
Actualizar la aplicación para mostrar la sección de texto
#Agrega un nuevo widget TextSection como hijo después de ButtonSection.
Al agregar el widget TextSection, establece su propiedad description con
el texto de la descripción de la ubicación.
location: 'Kandersteg, Switzerland',
),
ButtonSection(),
TextSection(
description:
'Lake Oeschinen lies at the foot of the Blüemlisalp in the '
'Bernese Alps. Situated 1,578 meters above sea level, it '
'is one of the larger Alpine Lakes. A gondola ride from '
'Kandersteg, followed by a half-hour walk through pastures '
'and pine forest, leads you to the lake, which warms to 20 '
'degrees Celsius in the summer. Activities enjoyed here '
'include rowing, and riding the summer toboggan run.',
),
],
Agregar la sección de Imagen
#En esta sección, agrega el archivo de imagen para completar tu diseño.
Configurar tu aplicación para usar las imágenes suministradas
#Para configurar tu aplicación para hacer referencia a imágenes, modifica su archivo pubspec.yaml.
Crea un directorio
imagesen la raíz del proyecto.-
Descarga la imagen
lake.jpgy agrégala al nuevo directorioimages. -
Para incluir imágenes, agrega una etiqueta
assetsal archivopubspec.yamlen el directorio raíz de tu aplicación. Cuando agregasassets, este sirve como el conjunto de punteros a las imágenes disponibles para tu código.pubspec.yamlyamlflutter: uses-material-design: true assets: - images/lake.jpg
Crear el widget ImageSection
#
Define el siguiente widget ImageSection después de las otras declaraciones.
class ImageSection extends StatelessWidget {
const ImageSection({super.key, required this.image});
final String image;
@override
Widget build(BuildContext context) {
return Image.asset(image, width: 600, height: 240, fit: BoxFit.cover);
}
}
El valor BoxFit.cover le dice a Flutter que muestre la imagen con
dos restricciones. Primero, mostrar la imagen tan pequeña como sea posible.
Segundo, cubrir todo el espacio asignado por el diseño, llamado la caja de renderizado (render box).
Actualizar la aplicación para mostrar la sección de imagen
#Agrega un widget ImageSection como el primer hijo en la lista children.
Establece la propiedad image en la ruta de la imagen que agregaste en
Configurar tu aplicación para usar las imágenes suministradas.
children: [
ImageSection(
image: 'images/lake.jpg',
),
TitleSection(
name: 'Oeschinen Lake Campground',
location: 'Kandersteg, Switzerland',
¡Felicitaciones!
#¡Eso es todo! Cuando realices un Hot Reload de la aplicación, tu aplicación debería verse así.
La aplicación terminada
Recursos
#Puedes acceder a los recursos utilizados en este tutorial desde estas ubicaciones:
Dart code: main.dart
Image: ch-photo
Pubspec: pubspec.yaml
Siguientes pasos
#Para agregar interactividad a este diseño, sigue el tutorial de interactividad.
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.