MDC-103 Flutter: Temas de Material con color, forma, elevación y tipo (Flutter)

logo_components_color_2x_web_96dp.png

Los componentes de Material (MDC) ayudan a los desarrolladores a implementar Material Design. MDC, creado por un equipo de ingenieros y diseñadores de UX en Google, cuenta con decenas de componentes de IU atractivos y funcionales, y está disponible para Android, iOS, la Web y Flutter.material.io/develop.

Ahora más que nunca puedes usar MDC para personalizar el estilo único de tus apps. La expansión reciente de Material Design les proporciona a los desarrolladores y diseñadores más flexibilidad para expresar la marca de sus productos.

En los codelabs MDC-101 y MDC-102, usaste componentes de Material (MDC) a fin de compilar los aspectos básicos de una app de comercio electrónico llamada Shrine, en la que se vende ropa y artículos para el hogar. Esta app incluye un flujo de usuarios que comienza con una pantalla de acceso y, luego, dirige al usuario a una pantalla principal en la que se muestran productos.

Qué compilarás

En este codelab, personalizarás la app de Shrine mediante los siguientes elementos:

  • Color
  • Tipografía
  • Elevación
  • Forma
  • Diseño

7f521db8a762f5ee.png 7ac46e5cb6b1e064.png

Componentes y subsistemas de MDC-Flutter de este codelab

  • Temas
  • Tipografía
  • Elevación
  • Lista de imágenes

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

Principiante Intermedio Avanzado

Antes de comenzar

A fin de comenzar a desarrollar apps para dispositivos móviles con Flutter, sigue estos pasos:

  1. Descarga e instala el SDK de Flutter.
  2. Actualiza tu PATH con el SDK de Flutter.
  3. Instala Android Studio con los complementos de Flutter y Dart, o tu editor favorito.
  4. Instala Android Emulator o un simulador de iOS (requiere una Mac con Xcode), o usa un dispositivo físico.

Para obtener más información sobre la instalación de Flutter, consulta Cómo comenzar: Instalación. Para configurar un editor, consulta Cómo comenzar: Configura un editor. Cuando instales Android Emulator, podrás usar las opciones predeterminadas, como un teléfono Pixel 3 con la imagen del sistema más reciente. Se recomienda, pero no es necesario, habilitar la aceleración de VM. Una vez que hayas completado los 4 pasos anteriores, podrás volver al codelab. Para completar este codelab, solo debes instalar Flutter en una plataforma (Android o iOS).

Asegúrate de que el SDK de Flutter esté en el estado correcto

Antes de continuar con este codelab, asegúrate de que el SDK esté en el estado correcto. Si el SDK de Flutter se instaló anteriormente, usa flutter upgrade para asegurarte de que el SDK esté en el estado más reciente.

 flutter upgrade

Si ejecutas flutter upgrade, se ejecutará automáticamente flutter doctor.. Si es una instalación nueva de Flutter y no necesitas actualizar nada, ejecuta flutter doctor de forma manual. Informará si hay dependencias que necesitas instalar para completar la configuración. Puedes ignorar las marcas de verificación que no sean relevantes para ti (por ejemplo, Xcode si no deseas desarrollar para iOS).

 flutter doctor

Preguntas frecuentes

¿Vienes de MDC-102?

Si completaste MDC-102, tu código debería estar listo para este codelab. Ve al paso Cambia los colores.

¿Empiezas de cero?

Descarga la app de inicio del codelab

Descargar app de inicio

La app de inicio se encuentra en el directorio material-components-flutter-codelabs-103-starter_and_102-complete/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 103-starter_and_102-complete

Cómo configurar tu proyecto

En las siguientes instrucciones, se da por sentado que usas Android Studio (IntelliJ).

Cómo abrir el proyecto

1. Abre Android Studio.

2. Si ves la pantalla de bienvenida, haz clic en Open an existing Android Studio project.

3. Navega al directorio material-components-flutter-codelabs/mdc_100_series y haz clic en "Open". Se debería abrir el proyecto. Puedes ignorar cualquier error que veas en Dart Analysis hasta que hayas compilado el proyecto una vez.

4. Si se te solicita, haz lo siguiente:

  • Instala cualquier actualización de plataforma y complemento o FlutterRunConfigurationType.
  • Si el SDK de Dart o Flutter no está configurado, establece la ruta del SDK de Flutter para el complemento de Flutter.
  • Configura los frameworks de Android.
  • Haz clic en "Get dependencies" o "Run 'flutter packages get'".

Luego, reinicia Android Studio.

Cómo ejecutar la app de inicio

En las siguientes instrucciones, se da por sentado que realizas la prueba en Android Emulator o un dispositivo Android, pero también puedes realizarla en un dispositivo o simulador de iOS si tienes instalado Xcode.

1. Selecciona el dispositivo o emulador. Si Android Emulator aún no se está ejecutando, selecciona Tools -> Android -> AVD Manager para crear un dispositivo virtual e iniciar el emulador. Si ya existe un AVD, puedes iniciar el emulador directamente desde el selector de dispositivos de Android Studio, como se muestra en el siguiente paso. (Para el simulador de iOS, si aún no se está ejecutando, selecciona Flutter Device Selection -> Open iOS Simulator para iniciarlo en la máquina de desarrollo).

2. Inicia tu app de Flutter:

  • Busca el menú desplegable "Flutter Device Selection" en la parte superior de la pantalla del editor y selecciona el dispositivo (por ejemplo, iPhone SE o Android SDK built for <versión>).
  • Presiona el ícono Reproducir ().

Listo. Deberías ver la página de acceso a Shrine de los codelabs anteriores en el simulador o el emulador.

Android

iOS

Haz clic en "Next" (siguiente) para ver la página principal del codelab anterior.

Android

iOS

Se creó un esquema de colores que representa la marca de Shrine, y al diseñador le gustaría que lo implementes en toda la app de Shrine.

Para comenzar, importa esos colores al proyecto.

Crea colors.dart

Crea un archivo Dart nuevo llamado colors.dart en lib. Importa componentes de Material y agrega valores const de color, como se muestra a continuación:

import 'package:flutter/material.dart';

const kShrinePink50 = Color(0xFFFEEAE6);
const kShrinePink100 = Color(0xFFFEDBD0);
const kShrinePink300 = Color(0xFFFBB8AC);
const kShrinePink400 = Color(0xFFEAA4A4);

const kShrineBrown900 = Color(0xFF442B2D);

const kShrineErrorRed = Color(0xFFC5032B);

const kShrineSurfaceWhite = Color(0xFFFFFBFA);
const kShrineBackgroundWhite = Colors.white;

Paleta de colores personalizados

Un diseñador creó este tema con colores personalizados (consulta la imagen más abajo). Contiene colores seleccionados de la marca de Shrine que se aplicaron en Material Theme Editor, donde se expandieron para crear una paleta más completa. (Estos colores no provienen de las paletas de colores de Material de 2014).

En Material Theme Editor, se organizan por matiz y están etiquetados de forma numérica, incluidas las etiquetas 50, 100, 200, y así sucesivamente hasta el 900, de cada color. Shrine solo usa los matices 50, 100 y 300 de la muestra rosa y el 900 de la muestra marrón.

wlq5aH94SfU47pcalUqOSK57OCX4HnJJTpMVzVrBZreUOE-CrkX2akKrnTbgwf6BQNMBi-nn16jpgQHDeQZixTCeh1A0qTXcxDMTcc2-e6uJg0LPjkXWEVlV7cwS0U1naqpnHToEIQ 1HLdzGp-TIhg2ULijquMw_KQdk18b080CVQN_oECAhiCnFI11Nm3nbcsCIXvZBXULMajAW9NEmGZ7iR_j-eEF6NiODuaike96xVpLwUIzfV4dzTg9uQHsmNG-BDTOd04e6_eRLs--Q

Cada parámetro con color de un widget se mapea a un color de estos esquemas. Por ejemplo, el color de las decoraciones de un campo de texto debería ser el primario del tema cuando se ingresa una entrada en el campo. Si ese color no es accesible (fácil de ver contra el fondo), usa PrimaryVariant en su lugar.

Las variaciones se crearon para los lineamientos de Material de 2014 y siguen disponibles en los lineamientos actuales (artículo del sistema de colores) y en MDC-Flutter. Para acceder a ellas en el código, llama al color de base y, luego, al matiz (por lo general un valor de centena). Por ejemplo, el comando Colors.pink[400] recupera el rosa 400.

Es perfectamente aceptable que uses estas paletas para tus diseños y tu código. Si tu marca ya tiene colores específicos, puedes generar tus propias paletas armoniosas con la herramienta de generación de paletas o con Material Theme Editor.

Ahora que ya tienes los colores que deseas usar, puedes aplicarlos a la IU. Para ello, debes configurar los valores de un widget ThemeData que aplicarás a la instancia de MaterialApp en la parte superior de la jerarquía de widgets.

Personaliza ThemeData.light()

Flutter incluye algunos temas integrados, como el tema claro. En lugar de crear un widget ThemeData desde cero, copiarás el tema claro y cambiarás los valores a fin de personalizarlos para la app.

Importa colors.dart en app.dart.

import 'colors.dart';

Luego, agrega lo siguiente a app.dart fuera del alcance de la clase ShrineApp:

// TODO: Build a Shrine Theme (103)
final ThemeData _kShrineTheme = _buildShrineTheme();

ThemeData _buildShrineTheme() {
  final ThemeData base = ThemeData.light();
  return base.copyWith(
    accentColor: kShrineBrown900,
    primaryColor: kShrinePink100,
    buttonTheme: base.buttonTheme.copyWith(
      buttonColor: kShrinePink100,
      colorScheme: base.colorScheme.copyWith(
        secondary: kShrineBrown900,
      ),
    ),
    buttonBarTheme: base.buttonBarTheme.copyWith(
      buttonTextTheme: ButtonTextTheme.accent,
    ),
    scaffoldBackgroundColor: kShrineBackgroundWhite,
    cardColor: kShrineBackgroundWhite,
    textSelectionColor: kShrinePink100,
    errorColor: kShrineErrorRed,
    // TODO: Add the text themes (103)
    // TODO: Add the icon themes (103)
    // TODO: Decorate the inputs (103)
  );
}

Ahora, configura theme: al final de la función build() de ShrineApp (en el widget MaterialApp) para que sea el nuevo tema.

  // TODO: Add a theme (103)
  theme: _kShrineTheme, // New code

Haz clic en el botón Reproducir. La pantalla de acceso debería verse de esta manera:

Android

iOS

Además, la pantalla principal debería tener el siguiente aspecto:

Android

iOS

Además de los cambios de color, el diseñador proporcionó una tipografía específica para usar. ThemeData de Flutter incluye 3 temas de texto. Cada tema de texto es una colección de estilos de texto, como "encabezado" y "título". Usarás algunos estilos para la app y cambiarás algunos valores.

Personaliza el tema de texto

A fin de importar fuentes al proyecto, las debes agregar al archivo pubspec.yaml.

En pubspec.yaml, agrega lo siguiente inmediatamente después de la etiqueta flutter::

  # TODO: Insert Fonts (103)
  fonts:
    - family: Rubik
      fonts:
        - asset: fonts/Rubik-Regular.ttf
        - asset: fonts/Rubik-Medium.ttf
          weight: 500

Ahora puedes acceder a la fuente Rubik y usarla.

Solución de problemas con el archivo pubspec

Es posible que se produzcan errores cuando ejecutes pub get si cortas y pegas la declaración anterior. En ese caso, quita el espacio en blanco inicial y reemplázalo con espacios que usen sangría de 2 espacios. Dos espacios antes de lo siguiente:

fonts:

Cuatro espacios antes de lo siguiente:

family: Rubik

Así sucesivamente.

Si aparece el mensaje Mapping values are not allowed here (aquí no se admiten valores de asignación), revisa la sangría de la línea que tiene el problema y la de las líneas superiores.

En login.dart, cambia lo siguiente dentro de Column():

Column(
  children: <Widget>[
    Image.asset('assets/diamond.png'),
    SizedBox(height: 16.0),
    Text(
      'SHRINE',
      style: Theme.of(context).textTheme.headline5,
    ),
  ],
)

En app.dart, agrega lo siguiente después de _buildShrineTheme():

// TODO: Build a Shrine Text Theme (103)
TextTheme _buildShrineTextTheme(TextTheme base) {
  return base.copyWith(
    headline5: base.headline5.copyWith(
      fontWeight: FontWeight.w500,
    ),
    headline6: base.headline6.copyWith(
        fontSize: 18.0
    ),
    caption: base.caption.copyWith(
      fontWeight: FontWeight.w400,
      fontSize: 14.0,
    ),
    bodyText1: base.bodyText1.copyWith(
      fontWeight: FontWeight.w500,
      fontSize: 16.0,
    ),
  ).apply(
    fontFamily: 'Rubik',
    displayColor: kShrineBrown900,
    bodyColor: kShrineBrown900,
  );
}

De esta manera, se toma un TextTheme y se cambia la apariencia de los encabezados, los títulos y las leyendas.

Si aplicas la fontFamily de esta forma, los cambios solo se aplicarán a los valores de escala de tipografía especificados en copyWith() (encabezado, título, leyenda).

Para algunas fuentes, configurarás un fontWeight predeterminado. El widget FontWeight tiene valores prácticos en las centenas. En las fuentes, w500 (el peso 500) es, por lo general, el mediano; w400 suele ser el normal.

Usa los nuevos temas de texto

Agrega los siguientes temas a _buildShrineTheme después de errorColor:

// TODO: Add the text themes (103)

textTheme: _buildShrineTextTheme(base.textTheme),
primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),

Haz clic en el botón Detener y, luego, en el botón Reproducir.

El texto se ve diferente en la pantalla principal y en la de acceso; parte del texto tiene la fuente Rubik y otra parte se renderiza en marrón, en lugar de blanco o negro.

Android

iOS

Observa que los íconos siguen siendo blancos, dado que los íconos tienen un tema independiente.

Utiliza un tema de ícono principal personalizado

Agrégalo a la función _buildShrineTheme() como se muestra a continuación:

    // TODO: Add the icon theme (103)
    primaryIconTheme: base.iconTheme.copyWith(
      color: kShrineBrown900
    ),

Haz clic en el botón Reproducir.

Android

iOS

Los íconos de la barra de la aplicación son marrones.

Reduce el texto

Las etiquetas son demasiado grandes.

En home.dart, cambia los children: de la columna más interna:

// TODO: Change innermost Column (103)
children: <Widget>[
// TODO: Handle overflowing labels (103)

  Text(
    product == null ? '' : product.name,
    style: theme.textTheme.button,
    softWrap: false,
    overflow: TextOverflow.ellipsis,
    maxLines: 1,
  ),
  SizedBox(height: 4.0),
  Text(
    product == null ? '' : formatter.format(product.price),
    style: theme.textTheme.caption,
  ),
  // End new code
],

Centra y suelta el texto

Debes centrar las etiquetas y alinear el texto hacia la parte inferior de cada tarjeta, en lugar de la parte inferior de cada imagen.

Mueve las etiquetas hacia el final (parte inferior) del eje principal y modifícalas para centrarlas, como se muestra a continuación:

// TODO: Align labels to the bottom and center (103)

  mainAxisAlignment: MainAxisAlignment.end,
  crossAxisAlignment: CrossAxisAlignment.center,

Guarda el proyecto.

Android

iOS

Está cerca, pero el texto aún no está centrado en la tarjeta.

Cambia la alineación del eje cruzado de la columna principal.

// TODO: Center items on the card (103)

    crossAxisAlignment: CrossAxisAlignment.center,

Guarda el proyecto. Ahora, la pantalla principal debería verse de esta manera:

Android

iOS

Así se ve mucho mejor.

Crea un tema de los campos de texto

Puedes crear un tema para la decoración de los campos de texto con un InputDecorationTheme.

En app.dart, en el método _buildShrineTheme(), especifica un valor inputDecorationTheme:.

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  border: OutlineInputBorder(),
),

Actualmente, los campos de texto tienen una decoración filled. Quita filled y especifica el inputDecorationTheme para darle el estilo de contorno a los campos de texto.

En login.dart, quita los valores filled: true, como se muestra a continuación:

// Remove filled: true values (103)
TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    // Removed filled: true
    labelText: 'Username',
  ),
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    // Removed filled: true
    labelText: 'Password',
  ),
  obscureText: true,
),

Haz clic en el botón para reiniciar en caliente de Flutter, en el menú Ejecutar, a fin de reiniciar la app desde el principio. La pantalla de acceso debería tener la siguiente apariencia cuando se activa el campo de nombre de usuario (mientras escribes en él):

Android

iOS

La tipografía de las decoraciones del campo de texto y el marcador de posición flotante se renderiza en el color principal. Sin embargo, no se ve con claridad. No es accesible para las personas que tienen dificultades para distinguir los píxeles cuando el contraste de color no es lo suficientemente alto. (Para obtener más información, consulta "Colores accesibles" en el artículo de colores de los lineamientos de Material). Especifica el objeto focusedBorder: en inputDecorationTheme: para anular el color de los elementos destacados a fin de que el campo de texto sea la PrimaryVariant que proporcionó el diseñador en el tema de color anterior.

En app.dart, especifica un elemento focusedBorder: en inputDecorationTheme:.

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  focusedBorder: OutlineInputBorder(
    borderSide: BorderSide(
      width: 2.0,
      color: kShrineBrown900,
    ),
  ),
  border: OutlineInputBorder(),
),

A continuación, cambiarás la propiedad labelStyle de los dos campos de texto para colorear la etiqueta con el tema que proporcionó el diseñador.

En login.dart, agrega labelStyle: en los dos widgets InputDecoration() de TextField.

TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    labelText: 'Username',
    labelStyle: TextStyle(color: Theme.of(context).accentColor),
  ),
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    labelText: 'Password',
    labelStyle: TextStyle(color: Theme.of(context).accentColor),
  ),
),

A fin de obtener diferentes estilos de etiquetas según si el campo de texto está enfocado o no, tendrás que configurar un FocusNode para cada uno de los widgets TextField, así como un condicional para que el labelStyle sea dinámico en función de si el widget está en foco.

En login.dart, inicializarás los FocusNodes y el color de la etiqueta sin enfocar en la parte superior de la clase _LoginPageState bajo los controladores de campo de texto.

class _LoginPageState extends State<LoginPage> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  final _unfocusedColor = Colors.grey[600];
  final _usernameFocusNode = FocusNode();
  final _passwordFocusNode = FocusNode();

Anula initState y agrega un objeto de escucha para los FocusNodes.

@override
void initState() {
  super.initState();
  _usernameFocusNode.addListener(() {
      setState(() {
        //Redraw so that the username label reflects the focus state
      });
   });
  _passwordFocusNode.addListener(() {
      setState(() {
        //Redraw so that the password label reflects the focus state
      });
   });
}

Por último, agrega la propiedad focusNode: en los widgets TextField y agrega un condicional para el labelStyle: en InputDecoration().

TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    labelText: 'Username',
    labelStyle: TextStyle(
        color: _usernameFocusNode.hasFocus
           ? Theme.of(context).accentColor
           : _unfocusedColor),
  ),
  focusNode: _usernameFocusNode,
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    labelText: 'Password',
    labelStyle: TextStyle(
        color: _passwordFocusNode.hasFocus
           ? Theme.of(context).accentColor
           : _unfocusedColor),
  ),
  focusNode: _passwordFocusNode,
),

Haz clic en el botón Reproducir.

Android

iOS

Ahora que aplicaste un estilo en la página con colores y tipografía específicos que combinan con Shrine, observa las tarjetas que muestran los productos de Shrine. Ahora, las tarjetas aparecen sobre una superficie blanca junto a la navegación del sitio.

Ajusta la elevación de la tarjeta

En home.dart, agrega un valor de elevation: a las tarjetas.

// TODO: Adjust card heights (103)

    elevation: 0.0,

Guarda el proyecto.

Android

iOS

Quitaste la sombra debajo de las tarjetas.

Ahora, cambiarás la elevación de los componentes en la pantalla de acceso para complementar la sombra.

Cambia la elevación del botón NEXT

La elevación predeterminada de los RaisedButtons es 2; vas a aumentarla.

En login.dart, agrega un valor de elevation: al RaisedButton NEXT.

RaisedButton(
  child: Text('NEXT'),
  elevation: 8.0, // New code

Haz clic en el botón para reiniciar en caliente de Flutter, en el menú Ejecutar, a fin de reiniciar la app desde el principio. La pantalla de acceso debería verse de esta manera:

Android

iOS

Shrine tiene un estilo geométrico atractivo y define los elementos con una forma octogonal o rectangular. Implementarás ese estilo de formas en las tarjetas de la pantalla principal, así como en los botones y los campos de texto de la pantalla de acceso.

Cambia las formas del campo de texto en la pantalla de acceso

En app.dart, importa un archivo especial de bordes de esquinas cortadas.

import 'supplemental/cut_corners_border.dart';

Aún en app.dart, agrega una forma con las esquinas cortadas al tema de decoración de campos de texto.

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  focusedBorder: CutCornersBorder(
    borderSide: BorderSide(
      width: 2.0,
      color: kShrineBrown900,
    ),
  ),
  border: CutCornersBorder(), // Replace code
),

Cambia las formas de los botones en la pantalla de acceso

En login.dart, agrega un borde rectangular biselado al botón CANCEL, como se muestra a continuación:

FlatButton(
  child: Text('CANCEL'),
  shape: BeveledRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(7.0)),
  ),

Si FlatButton no tiene una forma visible, ¿por qué agregarías una forma al borde? Se hace para que la animación de ondas esté vinculada a la misma forma cuando se toque.

Ahora, agrega la misma forma al botón NEXT.

RaisedButton(
  child: Text('NEXT'),
  elevation: 8.0,
  shape: BeveledRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(7.0)),
  ),

Para cambiar la forma de todos los botones, también puedes actualizar el buttonTheme en app.dart. Esto se propone como un desafío para el estudiante.

Haz clic en el botón para reiniciar en caliente de Flutter, en el menú Run (a fin de reiniciar la app desde el principio).

Android

iOS

A continuación, cambiarás el diseño para mostrar las tarjetas en diferentes tamaños y relaciones de aspecto, para que cada tarjeta tenga una apariencia única.

Reemplaza GridView por AsymmetricView

Ya escribiste los archivos para un diseño asimétrico.

En home.dart, cambia el archivo completo como se muestra a continuación:

import 'package:flutter/material.dart';

import 'model/products_repository.dart';
import 'model/product.dart';
import 'supplemental/asymmetric_view.dart';

class HomePage extends StatelessWidget {
  // TODO: Add a variable for Category (104)

  @override
  Widget build(BuildContext context) {
  // TODO: Return an AsymmetricView (104)
  // TODO: Pass Category variable to AsymmetricView (104)
    return Scaffold(
      appBar: AppBar(
        brightness: Brightness.light,
        leading: IconButton(
          icon: Icon(Icons.menu),
          onPressed: () {
            print('Menu button');
          },
        ),
        title: Text('SHRINE'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              print('Search button');
            },
          ),
          IconButton(
            icon: Icon(Icons.tune),
            onPressed: () {
              print('Filter button');
            },
          ),
        ],
      ),
      body: AsymmetricView(products: ProductsRepository.loadProducts(Category.all)),
    );
  }
}

Guarda el proyecto.

Android

iOS

Ahora, se puede desplazar por los productos de forma horizontal en un patrón que se asemeja al de un tejido. Además, el texto de la barra de estado (la hora y la red en la parte superior) ahora es negro. Esto se debe a que cambiamos el brillo de AppBar a claro: brightness: Brightness.light.

El color es una forma poderosa de expresar tu marca; un pequeño cambio de color puede generar un gran efecto en la experiencia del usuario. Para probarlo, observarás cómo se ve Shrine si el esquema de colores de la marca fuera completamente diferente.

Modifica los colores

En colors.dart, agrega el siguiente código:

const kShrinePurple = Color(0xFF5D1049);
const kShrineBlack = Color(0xFF000000);

En app.dart, cambia las funciones _buildShrineTheme() y _buildShrineTextTheme por lo siguiente:

ThemeData _buildShrineTheme() {
  final ThemeData base = ThemeData.light();
  return base.copyWith(
    primaryColor: kShrinePurple,
    buttonTheme: base.buttonTheme.copyWith(
      buttonColor: kShrinePurple,
      textTheme: ButtonTextTheme.primary,
      colorScheme: ColorScheme.light().copyWith(primary: kShrinePurple)
    ),
    scaffoldBackgroundColor: kShrineSurfaceWhite,
    textTheme: _buildShrineTextTheme(base.textTheme),
    primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
    accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
    primaryIconTheme: base.iconTheme.copyWith(
      color: kShrineSurfaceWhite
    ),
    inputDecorationTheme: InputDecorationTheme(
      focusedBorder: CutCornersBorder(
        borderSide: BorderSide(
          width: 2.0,
          color: kShrinePurple,
        ),
      ),
      border: CutCornersBorder(),
    ),
  );
}

TextTheme _buildShrineTextTheme(TextTheme base) {
  return base.copyWith(
    headline5: base.headline5.copyWith(
      fontWeight: FontWeight.w500,
    ),
    headline6: base.headline6.copyWith(
        fontSize: 18.0,
    ),
    caption: base.caption.copyWith(
      fontWeight: FontWeight.w400,
      fontSize: 14.0,
    ),
    bodyText1: base.bodyText1.copyWith(
      fontWeight: FontWeight.w500,
      fontSize: 16.0,
    ),
  ).apply(
    fontFamily: 'Rubik',
  );
}

En login.dart, cambia el color del diamante del logotipo a negro.

Image.asset(
  'assets/diamond.png',
  color: kShrineBlack, // New code
),

En home.dart, cambia el brillo de la AppBar a oscuro.

brightness: Brightness.dark,

Guarda el proyecto. Ahora, debería aparecer el tema nuevo.

Android

iOS

Android

iOS

El resultado es muy distinto. Antes de pasar a MDC-104, revertirás este código de color.

Descargar código de inicio de MDC-104

Ya creaste una app que se asemeja a las especificaciones de diseño que proporcionó el diseñador.

Próximos pasos

Ya utilizaste estos componentes de MDC: tema, tipografía, elevación y forma. En la biblioteca de MDC-Flutter, puedes explorar más componentes y subsistemas.

Examina los archivos del directorio supplemental para descubrir cómo creamos la cuadrícula de diseño asimétrico en la que se puede desplazar de forma horizontal.

¿Qué ocurre si el diseño que planificaste para tu app contiene elementos que no tienen componentes en la biblioteca de MDC? En MDC-104: Componentes avanzados de Material Design, se muestra cómo crear componentes personalizados con la biblioteca de MDC a fin de obtener un aspecto específico.

Siguiente codelab

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