MDC-103 Flutter : Utilisation des thèmes de Material Design (couleur, formes, élévation et type)

logo_components_color_2x_web_96dp.png

Material Components (MDC) aide les développeurs à implémenter Material Design. Conçu par une équipe d'ingénieurs et de spécialistes de l'expérience utilisateur chez Google, MDC propose des dizaines de composants d'interface utilisateur élégants et fonctionnels. Il est disponible pour Android, iOS, le Web et Flutter.material.io/develop.

Vous pouvez désormais utiliser MDC pour personnaliser comme jamais le style de vos applications. L'expansion récente de Material Design offre aux graphistes et aux développeurs une plus grande flexibilité pour exprimer la marque de leur produit.

Dans les ateliers de programmation MDC-101 et MDC-102, vous avez utilisé Material Components (MDC) pour concevoir les bases de Shrine, une application d'e-commerce pour la vente de vêtements et d'articles pour la maison. Le parcours utilisateur de cette application commence par un écran de connexion, puis se poursuit avec un écran d'accueil où sont affichés les produits.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez personnaliser les éléments suivants de l'application Shrine :

  • Couleur
  • Typographie
  • Élévation
  • Forme
  • Disposition

7f521db8a762f5ee.png 7ac46e5cb6b1e064.png

Composants et sous-systèmes de MDC-Flutter dans cet atelier de programmation

  • Thèmes
  • Typographie
  • Élévation
  • Liste d'images

Comment évalueriez-vous votre niveau d'expérience en développement avec Flutter ?

Débutant Intermédiaire Expert

Avant de commencer

Pour commencer à développer des applications mobiles avec Flutter, vous devez :

  1. télécharger et installer le SDK Flutter ;
  2. mettre à jour votre PATH avec le SDK Flutter ;
  3. installer Android Studio avec les plug-ins Flutter et Dart, ou votre éditeur préféré ;
  4. installer un émulateur Android, un simulateur iOS (nécessite un Mac avec Xcode) ou utiliser un appareil physique.

Pour plus d'informations sur l'installation de Flutter, consultez la section Premiers pas : Installation. Pour configurer un éditeur, consultez la section Premiers pas : Configurer un éditeur. Lorsque vous installez un émulateur Android, n'hésitez pas à utiliser les options par défaut, comme un téléphone Pixel 3 doté de la dernière image système. Il est conseillé, mais pas obligatoire, d'activer l'accélération de la VM. Une fois les quatre étapes ci-dessus effectuées, vous pouvez revenir à l'atelier de programmation. Pour cet atelier de programmation, vous avez seulement à installer Flutter pour une plate-forme (Android ou iOS).

Vérifier que la version de votre SDK Flutter est correcte

Avant de poursuivre cet atelier de programmation, assurez-vous que la version de votre SDK est correcte. Si le SDK Flutter a déjà été installé, utilisez flutter upgrade pour vous assurer qu'il s'agit de la dernière version.

 flutter upgrade

L'exécution de flutter upgrade lance automatiquement flutter doctor.. S'il s'agit d'une nouvelle installation de Flutter et qu'aucune mise à niveau n'est nécessaire, exécutez flutter doctor manuellement. Le système vous indique si vous devez installer des dépendances pour finaliser la configuration. Vous pouvez ignorer les options qui ne vous sont pas utiles (par exemple, Xcode si vous n'avez pas l'intention d'effectuer de développement pour iOS).

 flutter doctor

Questions fréquentes

Continuer à partir de MDC-102

Si vous avez fini l'atelier de programmation MDC-102, votre code devrait être prêt pour commencer cet atelier. Passez à l'étape Modifier les couleurs.

Vous partez de zéro ?

Télécharger l'application de départ de l'atelier de programmation

Télécharger l'application de départ

L'application de départ se trouve dans le répertoire material-components-flutter-codelabs-103-starter_and_102-complete/mdc_100_series.

... ou cloner l'atelier depuis GitHub

Pour cloner cet atelier de programmation à partir de GitHub, exécutez les commandes suivantes :

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

Configurer votre projet

Les instructions suivantes supposent que vous utilisez Android Studio (IntelliJ).

Ouvrir le projet

1. Ouvrez Android Studio.

2. Si l'écran de bienvenue s'affiche, cliquez sur Open an existing Android Studio project (Ouvrir un projet Android Studio existant).

3. Accédez au répertoire material-components-flutter-codelabs/mdc_100_series et cliquez sur "Open" (Ouvrir). Le projet devrait s'ouvrir. Vous pouvez ignorer toutes les erreurs qui s'affichent dans Dart Analysis jusqu'à ce que vous ayez créé un premier build du projet.

4. Si vous y êtes invité :

  • Installez les mises à jour de la plate-forme et des plug-ins ou FlutterRunConfigurationType.
  • Si le SDK Dart ou Flutter n'est pas configuré, définissez le chemin d'accès au SDK Flutter pour le plug-in Flutter.
  • Configurez les frameworks Android.
  • Cliquez sur "Get dependencies" (Obtenir les dépendances) ou sur "Run 'flutter package gets'" (Exécuter "flutter packages get").

Ensuite, redémarrez Android Studio.

Exécuter l'application de départ

Les instructions suivantes supposent que vous effectuez les tests sur un émulateur ou un appareil Android. Vous pouvez également les effectuer sur un simulateur ou un appareil iOS si Xcode est installé.

1. Sélectionnez l'appareil ou l'émulateur. Si l'émulateur Android ne s'exécute pas déjà, sélectionnez Tools > Android > AVD Manager (Outils > Android > AVD Manager) pour créer un appareil virtuel et lancer l'émulateur. Si un AVD existe déjà, vous pouvez lancer l'émulateur directement depuis le sélecteur d'appareil dans Android Studio, comme indiqué à l'étape suivante. Pour le simulateur iOS, s'il ne s'exécute pas déjà, lancez-le sur votre ordinateur de développement en sélectionnant Flutter Device Selection > Open iOS Simulator (Sélection d'appareils Flutter > Ouvrir le simulateur iOS).

2. Démarrez votre application Flutter :

  • Recherchez le menu déroulant "Flutter Device Selection" (Sélection des appareils Flutter) en haut de l'écran de votre éditeur, puis sélectionnez l'appareil (par exemple, iPhone SE ou Android SDK built for <version>).
  • Appuyez sur l'icône de lecture ().

Bravo ! La page de connexion de Shrine créée dans les précédents ateliers de programmation devrait s'afficher dans le simulateur ou l'émulateur.

Android

iOS

Cliquez sur "Next" (Suivant) pour afficher la page d'accueil de l'atelier de programmation précédent.

Android

iOS

Un jeu de couleurs a été créé pour représenter la marque Shrine, et le graphiste souhaite que vous l'implémentiez partout dans l'application Shrine.

Pour commencer, importons ces couleurs dans notre projet.

Créer colors.dart

Créez un fichier DART dans lib appelé colors.dart. Importez Material Components et ajoutez des constantes de couleurs :

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;

Personnaliser la palette de couleurs

Ce thème de couleur a été créé par un graphiste à partir de couleurs personnalisées (illustrées sur l'image ci-dessous). Il contient des couleurs sélectionnées à partir de la marque Shrine et appliquées à Material Theme Editor, une extension qui permet de créer une palette plus complète. Ces couleurs ne sont pas issues des palettes de couleurs de Material 2014).

Material Theme Editor les a organisées en nuances numérotées (libellés 50, 100, 200, etc. jusqu'à 900 pour chaque couleur). Shrine n'utilise que les nuances 50, 100 et 300 de l'échantillon rose, et 900 de l'échantillon marron.

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

Chaque paramètre de couleur d'un widget est associé à une couleur de ces nuances. Par exemple, la couleur des décorations d'un champ de texte dans lequel l'utilisateur saisit du texte doit être la couleur principale du thème. S'il n'est pas possible de se servir de cette couleur, car elle est difficile à distinguer de l'arrière-plan, utilisez plutôt la couleur PrimaryVariant.

Elles ont été créées pour les consignes Material 2014 et sont toujours disponibles dans les consignes actuelles (article Système de couleur) et dans MDC-Futter. Pour y accéder dans le code, il vous suffit d'appeler la couleur de base, puis la nuance (généralement un multiple de cent). Par exemple, la commande suivante permet de récupérer la couleur Rose 400 : Colors.pink[400].

Vous pouvez parfaitement utiliser ces palettes pour vos créations et votre code. Si vous disposez déjà de couleurs propres à votre branding, vous pouvez générer vos propres palettes harmonieuses à l'aide de l'outil de génération de palettes ou de Material Theme Editor.

Maintenant que nous avons récupéré les couleurs à utiliser, nous pouvons les appliquer à l'interface utilisateur. Pour ce faire, nous allons définir les valeurs d'un widget ThemeData, que nous appliquerons à l'instance MaterialApp au sommet de la hiérarchie des widgets.

Personnaliser ThemeData.light()

Flutter intègre quelques thèmes, dont le thème clair. Plutôt que de créer intégralement un widget ThemeData, nous allons copier le thème clair et modifier les valeurs afin de le personnaliser pour notre application.

Importez la chaîne colors.dart dans app.dart.

import 'colors.dart';

Ensuite, ajoutez le code suivant à app.dart en dehors du champ d'application de la classe 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)
  );
}

À présent, définissez theme: à la fin de la fonction build() de ShrineApp (dans le widget MaterialApp) comme nouveau thème :

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

Cliquez sur le bouton de lecture. L'écran de connexion devrait maintenant ressembler à ceci :

Android

iOS

Votre écran d'accueil devrait ressembler à ceci :

Android

iOS

En plus des modifications de couleur, le graphiste nous a fourni une typographie spécifique à utiliser. Le widget ThemeData de Flutter inclut trois thèmes de texte. Chacun d'entre eux est une collection de styles de texte, comme "en-tête" et "titre". Nous allons utiliser quelques styles pour notre application et modifier certaines valeurs.

Personnaliser le thème du texte

Pour importer des polices dans le projet, vous devez les ajouter au fichier pubspec.yaml.

Dans pubspec.yaml, ajoutez le code suivant immédiatement après la balise flutter: :

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

Vous pouvez à présent accéder à la police Rubik et l'utiliser.

Résoudre les problèmes liés au fichier pubspec

L'exécution de pub get peut renvoyer des erreurs si vous coupez et collez la déclaration ci-dessus. Si c'est le cas, commencez par supprimer l'espace blanc au début et remplacez-le par des espaces avec un retrait de 2 espaces (deux espaces avant

fonts:

, quatre espaces avant

family: Rubik

, et ainsi de suite).

Si le message Mapping values are not allowed here (Les valeurs de mappage ne sont pas autorisées ici) s'affiche, vérifiez le retrait de la ligne qui pose problème et celui des lignes au-dessus.

Dans login.dart, modifiez les éléments suivants dans Column() :

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

Dans app.dart, ajoutez le code suivant après _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,
  );
}

Cette opération prend un TextTheme et modifie l'apparence des en-têtes, des titres et des légendes.

Le fait d'appliquer fontFamily ainsi n'applique les modifications qu'aux valeurs d'échelle de typographie spécifiées dans copyWith() (en-tête, titre, légende).

Pour certaines polices, nous allons définir une épaisseur de police fontWeight personnalisée. Le widget FontWeight comporte des valeurs pratiques multiples de 100. Dans les polices, w500 (épaisseur de 500) est généralement l'épaisseur moyenne et w400 l'épaisseur standard.

Utiliser les nouveaux thèmes de texte

Ajoutez les thèmes suivants à _buildShrineTheme après errorColor :

// TODO: Add the text themes (103)

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

Cliquez sur le bouton "Stop" (Arrêter), puis sur le bouton de lecture.

Le texte des écrans de connexion et d'accueil change d'aspect : certains textes utilisent la police Rubik et d'autres apparaissent en marron, et non en noir ou blanc.

Android

iOS

Notez que les icônes sont toujours blanches. C'est parce qu'il existe un thème distinct pour les icônes.

Utiliser un thème d'icône principal personnalisé

Ajoutez le code suivant à la fonction _buildShrineTheme() :

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

Cliquez sur le bouton de lecture.

Android

iOS

Icônes marrons dans la barre d'application

Réduire le texte

Les libellés sont un peu trop grands.

Dans home.dart, modifiez children: de la colonne la plus au centre :

// 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
],

Centrer et déposer le texte

Nous voulons centrer les libellés et aligner le texte avec le bas de chaque carte plutôt qu'avec le bas de chaque image.

Déplacez les libellés jusqu'à la fin (bas) de l'axe principal et centrez-les :

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

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

Enregistrez le projet.

Android

iOS

On y est presque ! Mais il faut encore centrer le texte sur la carte.

Modifiez l'alignement horizontal de la colonne parent :

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

    crossAxisAlignment: CrossAxisAlignment.center,

Enregistrez le projet. Votre écran d'accueil devrait maintenant se présenter comme suit :

Android

iOS

Voilà qui est beaucoup mieux.

Appliquer un thème aux champs de texte

Vous pouvez également appliquer un thème à la décoration des champs de texte à l'aide d'une classe InputDecorationTheme.

Dans app.dart, dans la méthode _buildShrineTheme(), spécifiez une valeur inputDecorationTheme: :

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

Actuellement, les champs de texte comportent une décoration filled. Supprimons-la. Si vous supprimez filled et spécifiez inputDecorationTheme, le style de contour est appliqué aux champs de texte.

Dans login.dart, supprimez les valeurs filled: true :

// 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,
),

Pour redémarrer l'application depuis le début, cliquez sur le bouton "Flutter Hot Restart" (Redémarrage à chaud de Flutter) dans le menu "Run" (Exécuter). Votre écran de connexion devrait ressembler à ceci lorsque le champ "Username" (Nom d'utilisateur) est actif (c'est-à-dire lorsque vous saisissez votre nom d'utilisateur) :

Android

iOS

Saisissez du texte dans un champ de texte. Les décorations et l'espace réservé flottant s'affichent dans la couleur primaire. Mais il est difficile à distinguer. Il n'est pas visible par les personnes qui ont des difficultés à distinguer des pixels dont le contraste des couleurs est insuffisant. Pour en savoir plus, consultez la section "Accessible colors" (Couleurs accessibles) de l'article Color (Couleur) des consignes de Material Design. Dans cet exemple, nous allons spécifier focusedBorder: dans inputDecorationTheme: pour remplacer la couleur d'accentuation du champ de texte par la couleur PrimaryVariant que le graphiste nous a fournie dans le thème de couleurs ci-dessus.

Dans app.dart, spécifiez focusedBorder: sous inputDecorationTheme: :

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

Nous allons ensuite modifier la propriété labelStyle pour les deux champs de texte afin d'appliquer au libellé le thème de couleurs donné par le graphiste.

Dans login.dart, ajoutez labelStyle: sous les deux widgets TextField InputDecoration() :

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),
  ),
),

Afin que différents styles de libellés soient appliqués selon que le champ de texte est sélectionné ou non, nous devons configurer FocusNode pour chacun des widgets TextField, ainsi qu'une expression conditionnelle pour rendre le paramètre labelStyle dynamique selon que le widget est sélectionné ou non.

Dans login.dart, initialisons FocusNodes et la couleur de libellé non sélectionnée en haut de notre classe _LoginPageState sous les contrôleurs du champ de texte :

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

Remplacez initState et ajoutez un écouteur pour 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
      });
   });
}

Enfin, ajoutez la propriété focusNode: dans les widgets TextField, ainsi qu'une expression conditionnelle pour labelStyle: sous 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,
),

Cliquez sur le bouton de lecture.

Android

iOS

Maintenant que vous avez personnalisé la page avec une couleur et une typographie spécifiques correspondant à Shrine, penchons-nous sur les cartes qui présentent les produits de Shrine. À l'heure actuelle, les cartes sont placées sur une surface blanche, à côté du menu de navigation du site.

Ajuster l'élévation de la carte

Dans home.dart, ajoutez une valeur elevation: aux cartes :

// TODO: Adjust card heights (103)

    elevation: 0.0,

Enregistrez le projet.

Android

iOS

Vous avez supprimé l'ombre sous les cartes.

Modifions l'élévation des composants dans l'écran de connexion.

Modifier l'élévation du bouton NEXT (SUIVANT)

L'élévation par défaut de RaisedButtons est 2. On va l'augmenter.

Dans login.dart, ajoutez une valeur elevation: au RaisedButton NEXT (SUIVANT) :

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

Pour redémarrer l'application depuis le début, cliquez sur le bouton "Flutter Hot Restart" (Redémarrage à chaud de Flutter) dans le menu "Run" (Exécuter). L'écran de connexion devrait maintenant ressembler à ceci :

Android

iOS

Shrine présente un style géométrique tendance, dont les éléments sont de forme octogonale ou rectangulaire. Implémentons ce style de forme dans les cartes de l'écran d'accueil, ainsi que dans les champs de texte et les boutons de l'écran de connexion.

Modifier les formes des champs de texte dans l'écran de connexion

Dans app.dart, importez un fichier spécial de bordure d'angles coupés :

import 'supplemental/cut_corners_border.dart';

Toujours dans app.dart, ajoutez une forme avec des angles coupés au thème de décoration des champs de texte :

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

Modifier la forme des boutons dans l'écran de connexion

Dans login.dart, ajoutez une bordure rectangulaire biseautée au bouton CANCEL (ANNULER) :

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

Le FlatButton n'a pas de forme visible. Pourquoi faut-il donc ajouter une forme de bordure ? Pour que l'animation d'ondulation soit liée à la même forme lorsqu'un utilisateur appuie dessus.

Ajoutez à présent la même forme au bouton NEXT (SUIVANT) :

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

Pour modifier la forme de tous les boutons, nous pouvons également mettre à jour buttonTheme dans app.dart. Nous vous laissons relever ce défi tout seul !

Pour redémarrer l'application depuis le début, cliquez sur le bouton "Flutter Hot Restart" (Redémarrage à chaud de Flutter) dans le menu "Run" (Exécuter) :

Android

iOS

À présent, modifions la mise en page pour afficher les cartes dans différents formats et tailles, de sorte que chaque carte soit unique.

Remplacer GridView par AsymmetricView

Nous avons déjà écrit les fichiers pour une mise en page asymétrique.

Dans home.dart, modifiez le fichier complet comme suit :

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)),
    );
  }
}

Enregistrez le projet.

Android

iOS

Les produits défilent maintenant horizontalement, selon un modèle rappelant le tissage. De plus, le texte de la barre d'état (heure et réseau en haut) est désormais noir. En effet, nous avons réglé la luminosité de l'AppBar sur "clair", brightness: Brightness.light.

L'utilisation des couleurs est une manière puissante d'exprimer votre marque. Une légère modification de la couleur peut avoir un impact important sur l'expérience utilisateur. Pour tester cela, voyons à quoi ressemblerait Shrine si le jeu de couleurs de la marque était totalement différent.

Modifier les couleurs

Dans colors.dart, ajoutez le code suivant :

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

Dans app.dart, modifiez les fonctions _buildShrineTheme() et _buildShrineTextTheme comme suit :

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',
  );
}

Dans login.dart, appliquez la couleur noire au diamant du logo :

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

Dans home.dart, réglez la luminosité de AppBar sur sombre :

brightness: Brightness.dark,

Enregistrez le projet. Le nouveau thème devrait maintenant s'afficher.

Android

iOS

Android

iOS

Le résultat est très différent. Rétablissons ce code couleur avant de passer au module MDC-104.

Télécharger le code de départ de MDC-104

Vous venez de créer une application qui répond aux spécifications de design de votre graphiste.

Étapes suivantes

Vous avez utilisé les composants MDC suivants : les thèmes, la typographie, l'élévation et les formes. Vous pouvez découvrir d'autres composants et sous-systèmes dans la bibliothèque MDC-Flutter.

Parcourez les fichiers du répertoire supplemental pour voir comment nous avons réalisé la mise en page asymétrique en grille avec défilement horizontal.

Que se passe-t-il si le design prévu pour votre application contient des éléments dont les composants ne figurent pas dans la bibliothèque MDC ? Dans l'atelier de programmation MDC-104 : Composants avancés de Material Design, nous verrons comment créer des composants personnalisés à l'aide de la bibliothèque MDC pour obtenir un rendu spécifique.

Atelier de programmation suivant

La réalisation de cet atelier de programmation m'a demandé un temps et des efforts raisonnables

Tout à fait d'accord D'accord Ni d'accord, ni pas d'accord Pas d'accord Pas du tout d'accord

Je souhaite continuer à utiliser Material Components

Tout à fait d'accord D'accord Ni d'accord, ni pas d'accord Pas d'accord Pas du tout d'accord