MDC-101 Flutter: Conceptos básicos sobre los componentes de Material

1. Introducción

¿Qué son Material Design y la biblioteca de Material de Flutter?

Material Design es un sistema para crear productos digitales atractivos y llamativos. Mediante la unión de estilo, desarrollo de la marca, interacción y movimiento en un conjunto coherente de principios y componentes, los equipos de productos pueden alcanzar su máximo potencial de diseño.

La biblioteca de Material de Flutter incluye widgets de Flutter que implementan los diseños de los componentes de Material Design (MDC para crear una experiencia del usuario coherente en todas las apps y plataformas). A medida que evoluciona el sistema de Material Design, se actualizan estos componentes para garantizar una implementación uniforme pixel perfect, conforme a los estándares de desarrollo del frontend de Google.

En este codelab, compilarás una página de acceso con varios de los componentes de Material para Flutter.

Qué compilarás

Este codelab es el primero de cuatro que te guiarán para que crees una app llamada Shrine, una app de comercio electrónico en la que se vende ropa y artículos para el hogar. Demostrará cómo puedes personalizar los componentes para que reflejen cualquier marca o estilo con Flutter.

En este codelab, crearás una página de acceso para Shrine que contiene lo siguiente:

  • Una imagen del logotipo de Shrine
  • El nombre de la app (Shine)
  • Dos campos de texto: uno para ingresar un nombre de usuario y el otro para la contraseña
  • Dos botones

Android

iOS

Página de acceso al santuario en Android

Página de acceso al santuario en iOS

Componentes y subsistemas de Flutter de Material en este codelab

  • Campo de texto
  • Botón
  • Ondas de tinta (una forma visual de comentarios para eventos táctiles)

¿Cómo calificarías tu nivel de experiencia con el desarrollo de Flutter?

Principiante Intermedio Avanzado

2. Configura tu entorno de desarrollo de Flutter

Para completar este lab, necesitas dos programas de software: el SDK de Flutter y un editor.

Puedes ejecutar el codelab con cualquiera de estos dispositivos o modalidades:

  • Un dispositivo físico Android o iOS conectado a tu computadora y configurado en el Modo de desarrollador
  • El simulador de iOS (requiere instalar las herramientas de Xcode)
  • Android Emulator (requiere configuración en Android Studio)
  • Un navegador (se requiere Chrome para la depuración)
  • Como una aplicación para computadoras que ejecuten Windows, Linux o macOS (debes desarrollarla en la plataforma donde tengas pensado realizar la implementación; por lo tanto, si quieres desarrollar una app de escritorio para Windows, debes desarrollarla en ese SO a fin de obtener acceso a la cadena de compilación correcta; encuentra detalles sobre los requisitos específicos del sistema operativo en docs.flutter.dev/desktop).

3. Descarga la app de partida del codelab

El proyecto inicial se encuentra en el directorio material-components-flutter-codelabs-101-starter/mdc_100_series.

… o clónalo desde GitHub

Para clonar este codelab desde GitHub, ejecuta los siguientes comandos:

git clone https://github.com/material-components/material-components-flutter-codelabs.git
cd material-components-flutter-codelabs/mdc_100_series
git checkout 101-starter

Abre el proyecto y ejecuta la app

  1. Abre el proyecto en el editor que prefieras.
  2. Sigue las instrucciones para “ejecutar la app” en Get Started: Test drive en el editor que elegiste.

Listo El código de inicio para la página de acceso de Shrine debe estar ejecutándose en tu dispositivo. Deberías ver el logotipo de Shrine y el nombre "Shrine" debajo de él.

Android

iOS

Logotipo de Shrine

Logotipo de Shrine

Veamos el código.

Widgets en login.dart

Abre login.dart. Debe contener lo siguiente:

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  // TODO: Add text editing controllers (101)
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.symmetric(horizontal: 24.0),
          children: <Widget>[
            const SizedBox(height: 80.0),
            Column(
              children: <Widget>[
                Image.asset('assets/diamond.png'),
                const SizedBox(height: 16.0),
                const Text('SHRINE'),
              ],
            ),
            const SizedBox(height: 120.0),
            // TODO: Remove filled: true values (103)
            // TODO: Add TextField widgets (101)
            // TODO: Add button bar (101)
          ],
        ),
      ),
    );
  }
}

Ten en cuenta que contiene una sentencia import y dos clases nuevas:

  • La sentencia import permite usar la biblioteca de Material en este archivo.
  • La clase LoginPage representa toda la página que se muestra en el simulador.
  • La función build() de la clase _LoginPageState controla cómo se crean todos los widgets de nuestra IU.

4. Cómo agregar widgets de TextField

Para comenzar, agregaremos dos campos de texto a nuestra página de acceso, donde los usuarios ingresan su nombre de usuario y contraseña. Usaremos el widget TextField, que muestra una etiqueta flotante y activa un efecto de onda táctil.

Esta página se estructura principalmente con una ListView, que organiza sus elementos secundarios en una columna desplazable. Ingresemos campos de texto a continuación.

Cómo agregar los widgets de TextField

Agrega dos campos de texto nuevos y un espaciador después de const SizedBox(height: 120.0).

// TODO: Add TextField widgets (101)
// [Name]
TextField(
  decoration: const InputDecoration(
    filled: true,
    labelText: 'Username',
  ),
),
// spacer
const SizedBox(height: 12.0),
// [Password]
TextField(
  decoration: const InputDecoration(
    filled: true,
    labelText: 'Password',
  ),
  obscureText: true,
),

Cada campo de texto tiene un campo decoration: que toma un widget InputDecoration. El campo filled: significa que el fondo del campo de texto está levemente rellenado para ayudar a los usuarios a reconocer el área de presión o de objetivo táctil del campo de texto. El valor obscureText: true del segundo campo de texto reemplaza automáticamente la entrada que el usuario escribe con viñetas, y es apropiada para contraseñas.

Guarda tu proyecto (con la combinación de teclas: comando + s), que realiza una recarga en caliente.

Ahora debería ver una página con dos campos de texto para el nombre de usuario y la contraseña. Observa la animación de etiquetas flotantes:

Android

iOS

Logotipo de Shrine con campos de nombre de usuario y contraseña

Logotipo de Shrine con campos de nombre de usuario y contraseña

5. Cómo agregar botones

A continuación, agregaremos dos botones a nuestra página de acceso: "Cancel" y "Next". Usaremos dos tipos de widgets de botones: TextButton y ElevatedButton.

Agrega la barra de contenido adicional.

Después de los campos de texto, agrega OverflowBar a los elementos secundarios de ListView:

// TODO: Add button bar (101)
OverflowBar(
  alignment: MainAxisAlignment.end,
  // TODO: Add a beveled rectangular border to CANCEL (103)
  children: <Widget>[
    // TODO: Add buttons (101)
  ],
),

La OverflowBar organiza sus elementos secundarios en una fila.

Cómo agregar los botones

Luego, agrega dos botones a la lista de OverflowBar de children:

    // TODO: Add buttons (101)
    TextButton(
      child: const Text('CANCEL'),
      onPressed: () {
        // TODO: Clear the text fields (101)
      },
    ),
    // TODO: Add an elevation to NEXT (103)
    // TODO: Add a beveled rectangular border to NEXT (103)
    ElevatedButton(
      child: const Text('NEXT'),
      onPressed: () {
    // TODO: Show the next page (101)
      },
    ),

Guarda el proyecto. Debajo del último campo de texto, deberías ver dos botones:

Android

iOS

Logotipo de Shrine con campos de nombre de usuario y contraseña, botones Cancelar y Siguiente

Logotipo de Shrine con campos de nombre de usuario y contraseña, botones Cancelar y Siguiente

OverflowBar controla el trabajo de diseño por ti. Coloca los botones horizontalmente para que aparezcan uno al lado del otro.

Cuando se toca un botón, se inicia una animación de ondas de tinta, sin causar ningún otro resultado. Agreguemos funcionalidad a las funciones onPressed: anónimas para que el botón Cancel borre los campos de texto y el botón Next descarte la pantalla:

Cómo agregar TextEditingControllers

A fin de que sea posible borrar los valores de los campos de texto, agregaremos TextEditingControllers para controlar su texto.

Debajo de la declaración de la clase _LoginPageState, agrega los controladores como variables final.

  // TODO: Add text editing controllers (101)
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

En el campo controller: del primer campo de texto, configura _usernameController:

// TODO: Add TextField widgets (101)
// [Name]
TextField(
  controller: _usernameController,

En el campo controller: del segundo campo de texto, configura _passwordController:

// TODO: Add TextField widgets (101)
// [Password]
TextField(
  controller: _passwordController,

Cómo editar onPressed

Agrega un comando para borrar cada controlador en la función onPressed: de TextButton:

    // TODO: Clear the text fields (101)
    _usernameController.clear();
    _passwordController.clear();

Guarda el proyecto. Ahora, cuando escribas algo en los campos de texto, si presionas Cancel, se borrará cada campo nuevamente.

Este formulario de acceso se ve muy bien. Hagamos que nuestros usuarios avancen al resto de la app.

Quitar

Para descartar esta vista, queremos quitar esta página (lo que Flutter llama una ruta) fuera de la pila de navegación.

En la función onPressed: de ElevatedButton, abre la ruta más reciente de Navigator:

        // TODO: Show the next page (101)
        Navigator.pop(context);

Por último, abre home.dart y configura resizeToAvoidBottomInset como false en Scaffold:

    return Scaffold(
      // TODO: Add app bar (102)
      // TODO: Add a grid view (102)
      body: Center(
        child: Text('You did it!'),
      ),
      // TODO: Set resizeToAvoidBottomInset (101)
      resizeToAvoidBottomInset: false,
    );

Esto garantiza que la apariencia del teclado no altere el tamaño de la página principal o sus widgets.

Listo. Guarda el proyecto. Haz clic en "Next".

¡Excelente!

Android

iOS

Pantalla que dice 'Lo lograste'

Pantalla que dice 'Lo lograste'

Esta pantalla es el punto de partida para nuestro próximo codelab, que abordarás en MDC-102.

6. Felicitaciones

Agregamos campos y botones de texto, y casi no tuvimos que considerar el código de diseño. Los componentes de Material para Flutter vienen con mucho estilo y se pueden colocar en la pantalla casi sin esfuerzo.

Próximos pasos

Los campos de texto y los botones son dos componentes principales del sistema de Material, pero hay muchos más. También puedes explorar el resto en el catálogo de widgets de componentes de Material.

También puedes consultar MDC-102: Estructura y diseño de Material Design a fin de obtener información sobre los componentes que se abordan en MDC-102 para Flutter.

Pude completar este codelab con una cantidad de tiempo y esfuerzo razonables.

Totalmente de acuerdo De acuerdo Neutral En desacuerdo Totalmente en desacuerdo

Me gustaría seguir usando los componentes de Material en el futuro.

Totalmente de acuerdo De acuerdo Neutral En desacuerdo Totalmente en desacuerdo