1. Einführung
Material Components (MDC) unterstützen Entwickler bei der Implementierung von Material Design. MDC wurde von einem Team aus Entwicklern und UX-Designern bei Google entwickelt. Es enthält Dutzende schöne und funktionale UI-Komponenten und ist für Android, iOS, das Web und Flutter.material.io/develop verfügbar. |
Du kannst jetzt Material Flutter verwenden, um die unverwechselbaren Stil entwickeln. Die jüngste Erweiterung von Material Design bietet Designschaffenden und Entwickelnden mehr Flexibilität, die Marke ihres Produkts zum Ausdruck zu bringen.
In den Codelabs MDC-101 und MDC-102 haben Sie mithilfe von Material Flutter die Grundlagen einer App namens Shrine entwickelt. Das ist eine E-Commerce-App für den Verkauf von Kleidung und Haushaltswaren. Diese App enthält einen User Flow, der mit einem Anmeldebildschirm beginnt und den Nutzer dann zu einem Startbildschirm mit Produkten weiterleitet.
Inhalt
In diesem Codelab kannst du die Shrine-App anpassen:
- Farbe
- Typografie
- Höhe
- Form
- Layout
Android | iOS |
Codelab: Material Flutter-Komponenten und -Subsysteme
- Designs
- Typografie
- Höhe
- Bildliste
Wie würden Sie Ihre Erfahrung mit der Flutter-Entwicklung bewerten?
<ph type="x-smartling-placeholder">2. Flutter-Entwicklungsumgebung einrichten
Für dieses Lab benötigen Sie zwei Softwareprogramme: das Flutter SDK und einen Editor.
Sie können das Codelab auf jedem dieser Geräte ausführen:
- Ein physisches Android- oder iOS, das mit Ihrem Computer verbunden ist und sich im Entwicklermodus befindet.
- Den iOS-Simulator (erfordert die Installation von Xcode-Tools).
- Android-Emulator (Einrichtung in Android Studio erforderlich)
- Ein Browser (zur Fehlerbehebung wird Chrome benötigt)
- Als Windows-, Linux- oder macOS-Desktopanwendung Die Entwicklung muss auf der Plattform erfolgen, auf der Sie die Bereitstellung planen. Wenn Sie also eine Windows-Desktop-App entwickeln möchten, müssen Sie die Entwicklung unter Windows ausführen, damit Sie auf die entsprechende Build-Kette zugreifen können. Es gibt betriebssystemspezifische Anforderungen, die unter docs.flutter.dev/desktop ausführlich beschrieben werden.
3. Codelab-Starter-App herunterladen
Weiter mit MDC-102?
Wenn Sie MDC-102 abgeschlossen haben, sollte Ihr Code für dieses Codelab bereit sein. Fahren Sie mit dem Schritt Farben ändern fort.
Neu beginnen?
Starter-Codelab-App herunterladen
Die Start-App befindet sich im Verzeichnis material-components-flutter-codelabs-103-starter_and_102-complete/mdc_100_series
.
...oder von GitHub klonen
Führen Sie die folgenden Befehle aus, um dieses Codelab von GitHub zu klonen:
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
Projekt öffnen und App ausführen
- Öffnen Sie das Projekt in einem Editor Ihrer Wahl.
- Folgen Sie der Anleitung zum Ausführen der App. unter Erste Schritte: Testlauf für den ausgewählten Editor.
Fertig! Auf deinem Gerät sollte nun die Anmeldeseite von Shrine aus den vorherigen Codelabs angezeigt werden.
Android | iOS |
Klicken Sie auf „Weiter“. um die Produktseite aufzurufen.
Android | iOS |
4. Farben ändern
Es wurde ein Farbschema erstellt, das die Marke Shrine repräsentiert. Der Designer bittet Sie, dieses Farbschema in der Shrine-App zu implementieren.
Zunächst importieren wir diese Farben in unser Projekt.
Erstellen colors.dart
Erstellen Sie in lib
eine neue Dart-Datei mit dem Namen colors.dart
. Importieren Sie material.dart
und fügen Sie const Color
-Werte hinzu:
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;
Benutzerdefinierte Farbvorlage
Dieses Farbdesign wurde von einem Designer mit benutzerdefinierten Farben erstellt (siehe Bild unten). Sie enthält Farben, die aus der Marke Shrine ausgewählt und auf den Material Theme Editor angewendet wurden. Dieser hat sie erweitert, um eine umfassendere Palette zu erstellen. (Diese Farben stammen nicht aus den Farbvorlagen für Material von 2014.)
Im Material Theme Editor wurden sie in Schattierungen mit numerisch beschrifteten Schattierungen organisiert, einschließlich der Beschriftungen 50, 100, 200, ... bis 900 jeder Farbe. Shrine verwendet nur die Farbtöne 50, 100 und 300 aus dem rosa und 900 aus dem braunen Farbmuster.
Jeder Farbparameter eines Widgets wird einer Farbe aus diesen Schemas zugeordnet. Beispielsweise sollte die Farbe für die Dekoration eines Textfeldes, wenn aktiv Eingaben empfängt, die Primärfarbe des Designs sein. Ist diese Farbe nicht barrierefrei (gut erkennbar auf dem Hintergrund) vorhanden, verwenden Sie stattdessen eine andere Farbe.
Da wir nun die gewünschten Farben haben, können wir sie auf die Benutzeroberfläche anwenden. Dazu legen wir die Werte eines ThemeData-Widgets an, das wir auf die MaterialApp-Instanz ganz oben in unserer Widget-Hierarchie anwenden.
ThemeData.light() anpassen
Es gibt einige integrierte Designs für Flutter. Das helle Design ist eines davon. Anstatt ein ThemeData-Widget von Grund auf neu zu erstellen, kopieren wir das helle Design und ändern die Werte, um sie für unsere App anzupassen.
Importieren Sie colors.dart
in app.dart.
import 'colors.dart';
Fügen Sie dann Folgendes zu app.dart außerhalb des Bereichs der ShrineApp-Klasse hinzu:
// TODO: Build a Shrine Theme (103)
final ThemeData _kShrineTheme = _buildShrineTheme();
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light(useMaterial3: true);
return base.copyWith(
colorScheme: base.colorScheme.copyWith(
primary: kShrinePink100,
onPrimary: kShrineBrown900,
secondary: kShrineBrown900,
error: kShrineErrorRed,
),
// TODO: Add the text themes (103)
// TODO: Decorate the inputs (103)
);
}
Legen Sie nun theme:
am Ende der Funktion build()
von ShrineApp (im MaterialApp-Widget) als neues Design fest:
// TODO: Customize the theme (103)
theme: _kShrineTheme, // New code
Projekt speichern. Ihr Anmeldebildschirm sollte nun so aussehen:
Android | iOS |
5. Typografie und Labelstile ändern
Neben den Farbänderungen haben uns die Designschaffenden auch spezifische Typografie zur Verfügung gestellt. „ThemeData“ von Flutter umfasst drei Textthemen. Jedes Textdesign besteht aus einer Sammlung von Textstilen, z. B. „Anzeigentitel“. und „title“. Wir verwenden einige Stile für unsere App und ändern einige der Werte.
Textdesign anpassen
Schriftarten müssen der Datei pubspec.yaml hinzugefügt werden, um sie in das Projekt zu importieren.
Fügen Sie in der Datei pubspec.yaml direkt nach dem Tag flutter:
Folgendes hinzu:
# TODO: Insert Fonts (103)
fonts:
- family: Rubik
fonts:
- asset: fonts/Rubik-Regular.ttf
- asset: fonts/Rubik-Medium.ttf
weight: 500
Du kannst jetzt auf die Schriftart „Rubik“ zugreifen und sie verwenden.
Fehlerbehebung für die pubspec-Datei
Wenn Sie die Deklaration ausschneiden und einfügen, können beim Ausführen von pub get Fehler auftreten. Wenn Fehler auftreten, entfernen Sie zuerst das führende Leerzeichen und ersetzen Sie es durch Einrückung von zwei Leerzeichen durch Leerzeichen. (Zwei Leerzeichen vor
fonts:
, vier Leerzeichen davor
family: Rubik
usw.)
Wenn die Meldung Zuordnungswerte sind hier nicht zulässig angezeigt wird, überprüfen Sie den Einzug der Zeile, in der das Problem auftritt, und die Einrückung der Zeilen darüber.
Ändern Sie in login.dart
Folgendes innerhalb von Column()
:
Column(
children: <Widget>[
Image.asset('assets/diamond.png'),
const SizedBox(height: 16.0),
Text(
'SHRINE',
style: Theme.of(context).textTheme.headlineSmall,
),
],
)
Fügen Sie in app.dart
nach _buildShrineTheme()
Folgendes ein:
// TODO: Build a Shrine Text Theme (103)
TextTheme _buildShrineTextTheme(TextTheme base) {
return base
.copyWith(
headlineSmall: base.headlineSmall!.copyWith(
fontWeight: FontWeight.w500,
),
titleLarge: base.titleLarge!.copyWith(
fontSize: 18.0,
),
bodySmall: base.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14.0,
),
bodyLarge: base.bodyLarge!.copyWith(
fontWeight: FontWeight.w500,
fontSize: 16.0,
),
)
.apply(
fontFamily: 'Rubik',
displayColor: kShrineBrown900,
bodyColor: kShrineBrown900,
);
}
Dadurch wird anhand eines TextTheme-Elements das Aussehen der Überschriften, Titel und Untertitel geändert.
Wenn Sie fontFamily
auf diese Weise anwenden, werden die Änderungen nur auf die in copyWith()
angegebenen Werte für die typografische Skala angewendet (Anzeigentitel, Titel, Untertitel).
Für einige Schriftarten legen wir eine benutzerdefinierte Schriftstärke in Schritten von 100 fest: W500 (die Schriftstärke 500) entspricht mittel und w400 der Normalgröße.
Die neuen Text Hemes verwenden
Fügen Sie _buildShrineTheme
nach dem Fehler die folgenden Designs hinzu:
// TODO: Add the text themes (103)
textTheme: _buildShrineTextTheme(base.textTheme),
textSelectionTheme: const TextSelectionThemeData(
selectionColor: kShrinePink100,
),
Projekt speichern. Da wir die Schriftarten geändert haben, müssen Sie diesmal auch die App neu starten (Hot Neustart).
Android | iOS |
Der Text auf dem Anmelde- und Startbildschirm sieht anders aus: Einige Texte verwenden die Schriftart Rubik, während anderer Text braun statt schwarz oder weiß gerendert wird. Symbole werden ebenfalls braun dargestellt.
Text verkleinern
Die Labels sind zu groß.
Ändern Sie in home.dart
den children:
der innersten Spalte:
// TODO: Change innermost Column (103)
children: <Widget>[
// TODO: Handle overflowing labels (103)
Text(
product.name,
style: theme.textTheme.button,
softWrap: false,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
const SizedBox(height: 4.0),
Text(
formatter.format(product.price),
style: theme.textTheme.bodySmall,
),
// End new code
],
Text zentrieren und ablegen
Wir möchten die Beschriftungen zentrieren und den Text am unteren Rand jeder Karte ausrichten und nicht am unteren Rand jedes Bildes.
Verschieben Sie die Beschriftungen an das Ende (unten) der Hauptachse und legen Sie fest, dass sie zentriert sind:
// TODO: Align labels to the bottom and center (103)
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
Projekt speichern.
Android | iOS |
Das sieht viel besser aus.
Design der Textfelder
Sie können die Gestaltung von Textfeldern auch mit InputDecorationTheme gestalten.
Geben Sie in app.dart
in der Methode _buildShrineTheme()
einen inputDecorationTheme:
-Wert an:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
Im Moment sind die Textfelder filled
-dekoriert. Das entfernen wir. Wenn Sie filled
entfernen und inputDecorationTheme
angeben, erhalten die Textfelder den Umrissstil.
Entfernen Sie in login.dart
die Werte für filled: true
:
// Remove filled: true values (103)
TextField(
controller: _usernameController,
decoration: const InputDecoration(
// Removed filled: true
labelText: 'Username',
),
),
const SizedBox(height: 12.0),
TextField(
controller: _passwordController,
decoration: const InputDecoration(
// Removed filled: true
labelText: 'Password',
),
obscureText: true,
),
Neustart. Ihr Anmeldebildschirm sollte wie folgt aussehen, wenn das Feld Nutzername aktiv ist (wenn Sie es eingeben):
Android | iOS |
Geben Sie Text in ein Textfeld ein. Die Rahmen und unverankerten Labels werden in der Primärfarbe gerendert. Aber wir können es nicht so leicht sehen. Sie ist nicht zugänglich für Personen, die Probleme haben, Pixel mit einem nicht ausreichend hohen Farbkontrast zu unterscheiden. Weitere Informationen finden Sie im Artikel zu Farbe und Bedienungshilfen in den Materialrichtlinien.
Geben Sie in app.dart
einen focusedBorder:
unter inputDecorationTheme:
an :
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
),
Geben Sie als Nächstes unter inputDecorationTheme:
einen floatingLabelStyle:
an :
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
floatingLabelStyle: TextStyle(
color: kShrineBrown900,
),
),
Zum Schluss verwenden wir für die Schaltfläche „Cancel“ (Abbrechen) die sekundäre Farbe anstelle der primären Farbe, um den Kontrast zu erhöhen.
TextButton(
child: const Text('CANCEL'),
onPressed: () {
_usernameController.clear();
_passwordController.clear();
},
style: TextButton.styleFrom(
primary: Theme.of(context).colorScheme.secondary,
),
),
Projekt speichern.
Android | iOS |
6. Höhe anpassen
Nachdem Sie nun die Seite mit einer Farbe und einer bestimmten Typografie gestaltet haben, die zum Schrein passen, passen wir nun die Höhe an.
Höhe der Schaltfläche „WEITER“ ändern
Die Standardhöhe für ElevatedButton
ist 2. Erhöhen wir sie.
Fügen Sie in login.dart
dem ElevatedButton NEXT einen style:
-Wert hinzu:
ElevatedButton(
child: const Text('NEXT'),
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
elevation: 8.0,
),
),
Projekt speichern.
Android | iOS |
Höhe der Karte anpassen
Im Moment befanden sich die Karten auf einer weißen Fläche neben der Navigation der Website.
Füge in home.dart
den Infokarten einen elevation:
-Wert hinzu:
// TODO: Adjust card heights (103)
elevation: 0.0,
Speichern Sie das Projekt.
Android | iOS |
Sie haben den Schatten unter den Karten entfernt.
7. Form hinzufügen
Der Schrein hat einen coolen geometrischen Stil und definiert Elemente durch eine achteckige oder rechteckige Form. Implementieren Sie nun diesen Formstil in den Karten auf dem Startbildschirm sowie in die Textfelder und Schaltflächen auf dem Anmeldebildschirm.
Formen von Textfeldern auf dem Anmeldebildschirm ändern
Importieren Sie in app.dart
die folgende Datei:
import 'supplemental/cut_corners_border.dart';
Ändern Sie in app.dart
das Design für das Design des Textfelds, um einen Rahmen mit ausgeschnittenen Ecken zu verwenden:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: CutCornersBorder(),
focusedBorder: CutCornersBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
floatingLabelStyle: TextStyle(
color: kShrineBrown900,
),
),
Schaltflächenformen auf dem Anmeldebildschirm ändern
Fügen Sie in login.dart
der Schaltfläche ABBRECHEN einen abgeschrägten rechteckigen Rahmen hinzu:
TextButton(
child: const Text('CANCEL'),
onPressed: () {
_usernameController.clear();
_passwordController.clear();
},
style: TextButton.styleFrom(
foregroundColor: kShrineBrown900,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0)),
),
),
),
Der TextButton hat keine sichtbare Form. Warum sollte ich eine Rahmenform hinzufügen? Die Wellenanimation bleibt also beim Berühren an dieselbe Form gebunden.
Fügen Sie nun dieselbe Form zur Schaltfläche WEITER hinzu:
ElevatedButton(
child: const Text('NEXT'),
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
elevation: 8.0,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0)),
),
),
),
Um die Form aller Schaltflächen zu ändern, können wir auch elevatedButtonTheme
oder textButtonTheme
in app.dart
verwenden. Das bleibt eine Herausforderung für den Lernenden.
Neustart.
Android | iOS |
8. Layout ändern
Als Nächstes ändern wir das Layout, um die Karten mit unterschiedlichen Seitenverhältnissen und Größen anzuzeigen, sodass jede Karte von den anderen einzigartig aussieht.
GridView durch AsymmetricView ersetzen
Wir haben die Dateien für ein asymmetrisches Layout bereits geschrieben.
Fügen Sie in home.dart
den folgenden Import hinzu:
import 'supplemental/asymmetric_view.dart';
Löschen Sie _buildGridCards
und ersetzen Sie body
:
body: AsymmetricView(
products: ProductsRepository.loadProducts(Category.all),
),
Speichern Sie das Projekt.
Android | iOS |
Jetzt scrollen die Produkte horizontal in einem gewebt inspirierten Muster.
9. Anderes Design ausprobieren (optional)
Farbe ist ein wirkungsvolles Mittel, um Ihre Marke auszudrücken, und eine kleine Farbänderung kann einen großen Einfluss auf die User Experience haben. Um dies zu testen, sehen wir uns an, wie Shrine aussieht, wenn das Farbschema der Marke etwas anders wäre.
Farben ändern
Fügen Sie in colors.dart
die folgende Farbe hinzu:
const kShrinePurple = Color(0xFF5D1049);
Ändern Sie in app.dart
die Funktion _buildShrineTheme()
so:
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
colorScheme: base.colorScheme.copyWith(
primary: kShrinePurple,
secondary: kShrinePurple,
error: kShrineErrorRed,
),
scaffoldBackgroundColor: kShrineSurfaceWhite,
textSelectionTheme: const TextSelectionThemeData(
selectionColor: kShrinePurple,
),
appBarTheme: const AppBarTheme(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
),
inputDecorationTheme: const InputDecorationTheme(
border: CutCornersBorder(),
focusedBorder: CutCornersBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrinePurple,
),
),
floatingLabelStyle: TextStyle(
color: kShrinePurple,
),
),
);
}
Neustart. Das neue Design sollte jetzt angezeigt werden.
Android | iOS |
Android | iOS |
Das Ergebnis sieht ganz anders aus. app.dart's
_buildShrineTheme
wird auf den Zustand vor diesem Schritt zurückgesetzt. Du kannst auch den Startcode von 104 herunterladen.
10. Glückwunsch!
Inzwischen haben Sie eine App erstellt, die den Designspezifikationen Ihrer Designfachkraft ähnelt.
Weiteres Vorgehen
Sie haben jetzt das folgende Material Flutter verwendet: Design, Typografie, Elevation und Form. In der Material Flutter-Bibliothek finden Sie weitere Komponenten und Subsysteme.
Sehen Sie sich die Dateien im Verzeichnis supplemental
an, um zu erfahren, wie wir das horizontal scrollbare, asymmetrische Layoutraster erstellt haben.
Was ist, wenn Ihr geplantes App-Design Elemente enthält, für die keine Komponenten in der Bibliothek vorhanden sind? In MDC-104: Material Advanced Components wird gezeigt, wie Sie mithilfe der Material Flutter-Bibliothek benutzerdefinierte Komponenten erstellen, um den gewünschten Look zu erzielen.