MDC-103 Flutter: การให้ธีมวัสดุที่มีสี รูปทรง ระดับความสูง และประเภท

MDC-103 Flutter:
การให้ธีมวัสดุที่มีสี รูปทรง ระดับความสูง และประเภท

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ พ.ย. 14, 2023
account_circleเขียนโดย Material Flutter Team

1 บทนำ

logo_components_color_2x_web_96dp.png

Material Components (MDC) ช่วยให้นักพัฒนานำดีไซน์ Material มาใช้ MDC สร้างโดยทีมวิศวกรและนักออกแบบ UX ที่ Google โดยมีคอมโพเนนต์ UI ที่สวยงามและใช้งานได้หลายสิบอย่างและพร้อมใช้งานสำหรับ Android, iOS, เว็บ และ Flutter.material.io/develop

คุณใช้ Material Flutter เพื่อปรับแต่งแอปได้แล้ว มีสไตล์โดดเด่นกว่าที่เคย การขยายตัวล่าสุดของดีไซน์ Material ช่วยให้นักออกแบบและนักพัฒนาสามารถแสดงแบรนด์ของผลิตภัณฑ์ได้อย่างยืดหยุ่นมากขึ้น

ใน Codelabs MDC-101 และ MDC-102 คุณใช้ Material Flutter เพื่อสร้างข้อมูลพื้นฐานของแอปชื่อ Shrine ซึ่งเป็นแอปอีคอมเมิร์ซที่ขายเสื้อผ้าและของใช้ในบ้าน แอปนี้มีขั้นตอนการใช้งานของผู้ใช้ที่เริ่มต้นด้วยหน้าจอการเข้าสู่ระบบ จากนั้นจะนำผู้ใช้ไปยังหน้าจอหลักที่แสดงผลิตภัณฑ์

สิ่งที่คุณจะสร้าง

ใน Codelab นี้ คุณจะปรับแต่งแอป Shrine โดยใช้สิ่งต่อไปนี้

  • สี
  • การพิมพ์
  • ระดับความสูง
  • รูปร่าง
  • เลย์เอาต์

Android

iOS

หน้าเข้าสู่ระบบศาลเจ้า ธีมสีน้ำตาลและสีชมพู

หน้าเข้าสู่ระบบศาลเจ้า ธีมสีน้ำตาลและสีชมพู

หน้าผลิตภัณฑ์ของศาลเจ้าที่มีแถบแอปด้านบนและตารางกริดแบบอสมมาตรแบบเลื่อนได้แนวนอนซึ่งเต็มไปด้วยผลิตภัณฑ์ ธีมสีชมพู

คอมโพเนนต์และระบบย่อยของ Material Flutter ใน Codelab นี้

  • ธีม
  • การพิมพ์
  • ระดับความสูง
  • รายการรูปภาพ

โปรดให้คะแนนประสบการณ์การใช้งานการพัฒนา Flutter ของคุณ

2 ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ Flutter

ห้องทดลองนี้ต้องมีซอฟต์แวร์ 2 ประเภท ได้แก่ Flutter SDK และเครื่องมือแก้ไข

คุณเรียกใช้ Codelab ได้โดยใช้อุปกรณ์ต่อไปนี้

  • อุปกรณ์ Android หรือ iOS ที่เชื่อมต่อกับคอมพิวเตอร์และตั้งค่าเป็นโหมดนักพัฒนาซอฟต์แวร์
  • เครื่องมือจำลอง iOS (ต้องติดตั้งเครื่องมือ Xcode)
  • โปรแกรมจำลอง Android (ต้องตั้งค่าใน Android Studio)
  • เบราว์เซอร์ (การแก้ไขข้อบกพร่องต้องใช้ Chrome)
  • เป็นแอปพลิเคชัน Windows, Linux หรือ macOS บนเดสก์ท็อป คุณต้องพัฒนาบนแพลตฟอร์มที่คุณวางแผนจะทำให้ใช้งานได้ ดังนั้นหากต้องการพัฒนาแอป Windows บนเดสก์ท็อป คุณต้องพัฒนาบน Windows เพื่อเข้าถึงเชนบิลด์ที่เหมาะสม มีข้อกำหนดเฉพาะระบบปฏิบัติการที่ครอบคลุมรายละเอียดใน docs.flutter.dev/desktop

3 ดาวน์โหลดแอปเริ่มต้นสำหรับ Codelab

ต้องดำเนินการต่อจาก MDC-102 ใช่ไหม

หากคุณดำเนินการ MDC-102 เสร็จสมบูรณ์แล้ว โค้ดของคุณก็จะพร้อมใช้งานสำหรับ Codelab นี้ ข้ามไปยังขั้นตอน: เปลี่ยนสี

ต้องเริ่มต้นใหม่ใช่ไหม

ดาวน์โหลดแอป Codelab เริ่มต้น

แอปเริ่มต้นอยู่ในไดเรกทอรี material-components-flutter-codelabs-103-starter_and_102-complete/mdc_100_series

...หรือโคลนโมเดลจาก GitHub

หากต้องการโคลน Codelab นี้จาก GitHub ให้เรียกใช้คำสั่งต่อไปนี้

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

เปิดโปรเจ็กต์และเรียกใช้แอป

  1. เปิดโปรเจ็กต์ในเครื่องมือแก้ไขที่ต้องการ
  2. ทำตามวิธีการ "เรียกใช้แอป" ในเริ่มต้นใช้งาน: ทดลองใช้กับเครื่องมือแก้ไขที่คุณเลือก

สำเร็จ! คุณควรเห็นหน้าการเข้าสู่ระบบ Shrine จาก Codelab ก่อนหน้าบนอุปกรณ์ของคุณ

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าที่ไม่มีธีม

หน้าเข้าสู่ระบบของศาลเจ้าที่ไม่มีธีม

คลิก "ถัดไป" เพื่อดูหน้าผลิตภัณฑ์

Android

iOS

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่ไม่มีธีม

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่ไม่มีธีม

4 เปลี่ยนสี

ระบบได้สร้างรูปแบบสีที่แสดงถึงแบรนด์ Shrine แล้ว และนักออกแบบต้องการให้คุณใช้รูปแบบสีดังกล่าวในแอป Shrine

ในการเริ่มต้น ให้นำเข้าสีเหล่านั้นมายังโปรเจ็กต์ของเรา

สร้าง colors.dart

สร้างไฟล์ปาเป้าใหม่ใน lib ชื่อ colors.dart นำเข้า material.dart และเพิ่มค่า const Color รายการ

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;

ชุดสีที่กำหนดเอง

ธีมสีนี้สร้างขึ้นโดยนักออกแบบที่มีสีแบบกำหนดเอง (แสดงในภาพด้านล่าง) ซึ่งมีสีที่คัดสรรมาจากแบรนด์ของ Shrine แล้วนำไปใช้กับเครื่องมือแก้ไขธีมของวัสดุ ซึ่งได้ขยายสีเหล่านั้นเพื่อสร้างจานสีที่สมบูรณ์ยิ่งขึ้น (สีเหล่านี้ไม่ได้มาจากชุดสี Material ปี 2014)

เครื่องมือแก้ไขธีมของวัสดุได้จัดระเบียบธีมต่างๆ ออกเป็นเฉดสีพร้อมป้ายกำกับตัวเลข ได้แก่ ป้ายกำกับ 50, 100, 200, .... ถึง 900 สำหรับสีแต่ละสี Shrine ใช้เฉดสี 50, 100 และ 300 จากตัวอย่างสีชมพู และ 900 จากตัวอย่างแผ่นสีน้ำตาล

d0362cb45c565a8e.jpeg 470b0e1c2669ae2.png

พารามิเตอร์สีของวิดเจ็ตแต่ละรายการจะจับคู่กับสีจากรูปแบบเหล่านี้ ตัวอย่างเช่น สีสำหรับการตกแต่งช่องข้อความเมื่อช่องรับอินพุตอยู่ควรเป็นสีหลักของธีม หากเข้าถึงสีนั้นไม่ได้ (มองเห็นได้ง่ายบนพื้นหลัง) ให้ใช้สีอื่นแทน

เมื่อเรามีสีที่ต้องการใช้แล้ว เราก็สามารถนำไปใช้กับ UI ได้ โดยการกำหนดมูลค่าของวิดเจ็ต ThemeData ที่ใช้กับอินสแตนซ์ MaterialApp ระดับบนสุดของลำดับชั้นวิดเจ็ต

ปรับแต่ง ThemeData.light()

Flutter มีธีมในตัวอยู่ 2-3 ธีม ธีมสว่างก็เป็นหนึ่งในนั้น เราจะคัดลอกธีมสว่างและเปลี่ยนค่าเพื่อปรับแต่งแอปให้เข้ากับแอป แทนที่จะสร้างวิดเจ็ต ThemeData ตั้งแต่ต้น

มานำเข้า colors.dart ใน app.dart. กัน

import 'colors.dart';

จากนั้นเพิ่มข้อมูลต่อไปนี้ลงใน app.dart ภายนอกขอบเขตของคลาส ShrineApp

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

ตอนนี้ ให้ตั้งค่า theme: ที่ส่วนท้ายของฟังก์ชัน build() ของ ShrineApp (ในวิดเจ็ต MaterialApp) เป็นธีมใหม่ของเรา

  // TODO: Customize the theme (103)
  theme: _kShrineTheme, // New code

บันทึกโปรเจ็กต์ หน้าจอการเข้าสู่ระบบของคุณควรมีลักษณะดังนี้

Android

iOS

หน้าเข้าสู่ระบบศาลเจ้าสีชมพูและน้ำตาล

หน้าเข้าสู่ระบบศาลเจ้าสีชมพูและน้ำตาล

5 แก้ไขการออกแบบตัวอักษรและรูปแบบป้ายกำกับ

นอกจากการเปลี่ยนสีแล้ว ผู้ออกแบบยังได้พิมพ์ตัวอักษรที่เฉพาะเจาะจงให้เราใช้ด้วย ThemeData ของ Flutter มีธีมข้อความ 3 รายการ ธีมข้อความแต่ละธีมคือคอลเล็กชันของรูปแบบข้อความ เช่น "บรรทัดแรก" และ "title" เราจะใช้รูปแบบ 2-3 รูปแบบสำหรับแอปและเปลี่ยนค่าบางอย่าง

ปรับแต่งธีมข้อความ

หากต้องการนำเข้าแบบอักษรลงในโปรเจ็กต์ คุณจะต้องเพิ่มแบบอักษรลงในไฟล์ pubspec.yaml

ใน pubspec.yaml ให้เพิ่มข้อมูลต่อไปนี้หลังแท็ก flutter:

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

ตอนนี้คุณสามารถเข้าถึงและใช้แบบอักษรรูบิกได้แล้ว

การแก้ปัญหาไฟล์ pubspec

คุณอาจได้รับข้อผิดพลาดในการเรียกใช้ pub get หากตัดและวางการประกาศข้างต้น หากพบข้อผิดพลาด ให้เริ่มต้นด้วยการนําช่องว่างขึ้นต้นออก แล้วแทนที่ด้วยการเว้นวรรคโดยใช้การเยื้อง 2 ช่อง (ก่อนเว้นวรรคสองช่อง

fonts:

ก่อนเว้นวรรค 4 ครั้ง

family: Rubik

เป็นต้น)

ถ้าคุณเห็นไม่อนุญาตให้ใช้ค่าการแมปที่นี่ ให้ตรวจสอบการเยื้องของบรรทัดที่มีปัญหาและการเยื้องของบรรทัดที่ด้านบน

ใน login.dart ให้เปลี่ยนรายการต่อไปนี้ใน Column()

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

ใน app.dart ให้เพิ่มข้อมูลต่อไปนี้หลัง _buildShrineTheme()

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

ซึ่งจะใช้ TextTheme และเปลี่ยนรูปลักษณ์ของบรรทัดแรก ชื่อ และคำบรรยายแทนเสียง

การใช้ fontFamily ในลักษณะนี้จะใช้การเปลี่ยนแปลงกับค่าสเกลการพิมพ์ที่ระบุไว้ใน copyWith() (บรรทัดแรก ชื่อ คำบรรยายภาพ) เท่านั้น

สำหรับแบบอักษรบางแบบ เราจะตั้งค่าน้ำหนักแบบอักษรที่กำหนดเอง โดยเพิ่มขึ้นทีละ 100: w500 (น้ำหนัก 500) จะสอดคล้องกับขนาดกลาง ส่วน w400 จะเท่ากับขนาดปกติ

ใช้ธีมใหม่

เพิ่มธีมต่อไปนี้ใน _buildShrineTheme หลังจากเกิดข้อผิดพลาด:

// TODO: Add the text themes (103)
textTheme: _buildShrineTextTheme(base.textTheme),
textSelectionTheme: const TextSelectionThemeData(
  selectionColor: kShrinePink100,
),

บันทึกโปรเจ็กต์ แต่ครั้งนี้ให้รีสตาร์ทแอปด้วย (หรือที่เรียกกันว่า Hot Restart) เนื่องจากเราได้แก้ไขแบบอักษร

Android

iOS

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่ใช้ธีมข้อความ

ข้อความในหน้าจอเข้าสู่ระบบและหน้าจอหลักมีลักษณะแตกต่างกัน ข้อความบางส่วนใช้แบบอักษรรูบิก และข้อความอื่นๆ แสดงเป็นสีน้ำตาลแทนที่จะเป็นสีดำหรือสีขาว ไอคอนก็จะแสดงเป็นสีน้ำตาลด้วย

ย่อข้อความ

ป้ายกำกับมีขนาดใหญ่เกินไป

ใน home.dart ให้เปลี่ยน children: ของคอลัมน์ด้านในสุด:

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

กึ่งกลางและวางข้อความ

เราต้องการจัดป้ายกำกับไว้ตรงกลาง และปรับข้อความให้อยู่ด้านล่างของการ์ดแต่ละใบ แทนที่จะเป็นด้านล่างของแต่ละรูปภาพ

ย้ายป้ายกำกับไปจนสุด (ด้านล่าง) ของแกนหลัก แล้วเปลี่ยนให้อยู่กึ่งกลาง โดยทำดังนี้

  // TODO: Align labels to the bottom and center (103)
  mainAxisAlignment: MainAxisAlignment.end,
  crossAxisAlignment: CrossAxisAlignment.center,

บันทึกโปรเจ็กต์

Android

iOS

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่มีการจัดข้อความที่แตกต่างกัน

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่มีการจัดข้อความที่แตกต่างกัน

ดูดีขึ้นมากเลย

กำหนดธีมให้ช่องข้อความ

คุณยังกำหนดธีมของการตกแต่งในช่องข้อความด้วย InputDecorationTheme ได้อีกด้วย

ใน app.dart ในเมธอด _buildShrineTheme() ให้ระบุค่า inputDecorationTheme: ดังนี้

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

ขณะนี้ช่องข้อความมีการตกแต่ง filled ลบรูปนั้นออกไป การนำ filled ออกและระบุ inputDecorationTheme จะทำให้ช่องข้อความมีรูปแบบเค้าโครง

ใน login.dart ให้นำค่า 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,
),

ฮอตรีสตาร์ท หน้าจอการเข้าสู่ระบบของคุณควรมีลักษณะเช่นนี้เมื่อมีการใช้งานฟิลด์ ชื่อผู้ใช้ (เมื่อคุณพิมพ์ลงไป):

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าที่โฟกัสช่องชื่อผู้ใช้

หน้าเข้าสู่ระบบของศาลเจ้าที่โฟกัสช่องชื่อผู้ใช้

พิมพ์ลงในช่องข้อความ โดยเส้นขอบและป้ายกำกับแบบลอยจะแสดงด้วยสีหลัก แต่เราเห็นมันได้ยาก ผู้ที่มีปัญหาในการแยกพิกเซลที่มีคอนทราสต์ของสีไม่สูงพอจะไม่สามารถเข้าถึงได้ (สำหรับข้อมูลเพิ่มเติม โปรดดูบทความเกี่ยวกับสีและการเข้าถึงของหลักเกณฑ์ด้านวัสดุ)

ใน app.dart ให้ระบุ focusedBorder: ภายใต้ inputDecorationTheme: :

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

ถัดไป ให้ระบุ floatingLabelStyle: ใน inputDecorationTheme: :

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

สุดท้าย ขอให้ปุ่ม "ยกเลิก" ใช้สีรองแทนสีหลัก เพื่อเพิ่มคอนทราสต์

TextButton(
  child: const Text('CANCEL'),
  onPressed: () {
    _usernameController.clear();
    _passwordController.clear();
  },
  style: TextButton.styleFrom(
    primary: Theme.of(context).colorScheme.secondary,
  ),
),

บันทึกโปรเจ็กต์

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าที่มีปุ่มยกเลิกเข้าถึงได้

หน้าเข้าสู่ระบบของศาลเจ้าที่มีปุ่มยกเลิกเข้าถึงได้

6 ปรับระดับความสูง

เมื่อคุณได้จัดรูปแบบหน้าด้วยสีและแบบอักษรเฉพาะที่ตรงกับ Shrine แล้ว มาปรับระดับความสูงกัน

เปลี่ยนระดับความสูงของปุ่ม "ถัดไป"

ระดับความสูงเริ่มต้นสำหรับ ElevatedButton คือ 2 ทำให้สูงขึ้นอีกหน่อย

ใน login.dart ให้เพิ่มค่า style: ในปุ่ม ถัดไป แบบยกระดับ:

ElevatedButton(
  child: const Text('NEXT'),
  onPressed: () {
    Navigator.pop(context);
  },
  style: ElevatedButton.styleFrom(
    foregroundColor: kShrineBrown900,
    backgroundColor: kShrinePink100,
    elevation: 8.0,
  ),
),

บันทึกโปรเจ็กต์

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าพร้อมปุ่ม NEXT ที่ยกขึ้น

หน้าเข้าสู่ระบบของศาลเจ้าพร้อมปุ่ม NEXT ที่ยกขึ้น

ปรับระดับความสูงของการ์ด

โดยในขณะนี้ การ์ดจะอยู่บนพื้นผิวสีขาวถัดจากการนำทางของเว็บไซต์

ใน home.dart ให้เพิ่มค่า elevation: ลงในการ์ด ดังนี้

// TODO: Adjust card heights (103)
elevation: 0.0,

บันทึกโปรเจ็กต์

Android

iOS

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่ไม่มีระดับความสูงสำหรับการ์ดแต่ละใบ

หน้าตารางกริดสำหรับผลิตภัณฑ์ของศาลเจ้าที่ไม่มีระดับความสูงสำหรับการ์ดแต่ละใบ

คุณได้นำเงาใต้การ์ดออกแล้ว

7 เพิ่มรูปร่าง

ศาลเจ้ามีรูปแบบเรขาคณิตสุดเก๋ที่กำหนดองค์ประกอบด้วยรูปทรงแปดเหลี่ยมหรือสี่เหลี่ยมผืนผ้า เราลองมาลองใช้การจัดรูปแบบของรูปร่างนั้นในการ์ดบนหน้าจอหลัก รวมถึงช่องข้อความและปุ่มในหน้าจอการเข้าสู่ระบบ

เปลี่ยนรูปร่างของช่องข้อความในหน้าจอการเข้าสู่ระบบ

ใน app.dart ให้นำเข้าไฟล์ต่อไปนี้

import 'supplemental/cut_corners_border.dart';

ยังคงอยู่ใน app.dart ให้แก้ไขธีมการตกแต่งช่องข้อความเพื่อใช้เส้นขอบแบบตัดมุม

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

เปลี่ยนรูปร่างของปุ่มในหน้าจอการเข้าสู่ระบบ

ใน login.dart ให้เพิ่มเส้นขอบสี่เหลี่ยมผืนผ้าแบบนูนลงในปุ่มยกเลิก ดังนี้

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

TextButton ไม่มีรูปร่างที่มองเห็นได้ แล้วทำไมจึงต้องเพิ่มรูปร่างเส้นขอบ ภาพเคลื่อนไหวแบบระลอกคลื่นจะถูกผูกไว้กับรูปทรงเดียวกันเมื่อแตะ

ตอนนี้ให้เพิ่มรูปร่างเดียวกันลงในปุ่ม "ถัดไป":

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

หากต้องการเปลี่ยนรูปร่างของปุ่มทั้งหมด เราสามารถใช้ elevatedButtonTheme หรือ textButtonTheme ใน app.dart ได้เช่นกัน จึงเป็นความท้าทายสำหรับผู้เรียน

ฮอตรีสตาร์ท

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าที่ใช้ธีมรูปร่าง

หน้าเข้าสู่ระบบของศาลเจ้าที่ใช้ธีมรูปร่าง

8 เปลี่ยนเลย์เอาต์

ถัดไป เรามาเปลี่ยนเลย์เอาต์เพื่อแสดงการ์ดในสัดส่วนภาพและขนาดต่างๆ เพื่อให้การ์ดแต่ละใบดูไม่ซ้ำกัน

แทนที่ GridView ด้วย AsymmetricView

เราได้เขียนไฟล์สำหรับรูปแบบอสมมาตรแล้ว

ใน home.dart ให้เพิ่มการนำเข้าต่อไปนี้

import 'supplemental/asymmetric_view.dart';

ลบ _buildGridCards และแทนที่ body:

body: AsymmetricView(
  products: ProductsRepository.loadProducts(Category.all),
),

บันทึกโปรเจ็กต์

Android

iOS

หน้าผลิตภัณฑ์ของศาลเจ้าที่มีเลย์เอาต์แบบเลื่อนในแนวนอนได้แบบอสมมาตร

หน้าผลิตภัณฑ์ของศาลเจ้าที่มีเลย์เอาต์แบบเลื่อนในแนวนอนได้แบบอสมมาตร

ตอนนี้ผลิตภัณฑ์จะเลื่อนในแนวนอนเป็นลวดลายถักทอ

9 ลองใช้ธีมอื่น (ไม่บังคับ)

สีเป็นวิธีที่มีประสิทธิภาพในการแสดงออกถึงแบรนด์ของคุณ และการเปลี่ยนสีเพียงเล็กน้อยอาจมีผลกระทบอย่างมากต่อประสบการณ์ของผู้ใช้ เรามาทดสอบกันว่า Shrine มีลักษณะเป็นอย่างไร ถ้ารูปแบบสีของแบรนด์ต่างออกไปเล็กน้อย

แก้ไขสี

ใน colors.dart ให้เพิ่มสีต่อไปนี้

const kShrinePurple = Color(0xFF5D1049);

ใน app.dart ให้เปลี่ยนฟังก์ชัน _buildShrineTheme() เป็นดังนี้

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

ฮอตรีสตาร์ท ธีมใหม่จะปรากฏขึ้น

Android

iOS

หน้าเข้าสู่ระบบของศาลเจ้าในธีมสีม่วงและชมพู

หน้าเข้าสู่ระบบของศาลเจ้าในธีมสีม่วงและชมพู

Android

iOS

หน้าผลิตภัณฑ์ของศาลเจ้าในธีมสีชมพู

หน้าผลิตภัณฑ์ของศาลเจ้าในธีมสีชมพู

ผลลัพธ์แตกต่างกันมาก มาเปลี่ยน app.dart's _buildShrineTheme กลับไปเป็นค่าเดิมก่อนขั้นตอนนี้กัน หรือดาวน์โหลดรหัสเริ่มต้นของ 104

10 ยินดีด้วย

ถึงตอนนี้ คุณได้สร้างแอปที่คล้ายกับข้อกำหนดการออกแบบจากนักออกแบบของคุณ

ขั้นตอนถัดไป

คุณใช้ Material Flutter ต่อไปนี้ ซึ่งได้แก่ ธีม การพิมพ์ ระดับความสูง และรูปร่าง คุณสำรวจคอมโพเนนต์และระบบย่อยเพิ่มเติมได้ในไลบรารี Material Flutter

เจาะลึกไฟล์ในไดเรกทอรี supplemental เพื่อดูวิธีที่เราสร้างตารางกริดเลย์เอาต์แบบอสมมาตรในแนวนอน

จะเป็นอย่างไรหากการออกแบบแอปที่วางแผนไว้มีองค์ประกอบที่ไม่มีคอมโพเนนต์ในไลบรารี ใน MDC-104: Material Advanced Components เราจะแสดงวิธีสร้างคอมโพเนนต์ที่กำหนดเองโดยใช้ไลบรารี Material Flutter เพื่อให้ได้รูปลักษณ์ที่ต้องการ

ฉันทำ Codelab นี้เสร็จได้ โดยใช้เวลาและลงแรงพอสมควร

ฉันต้องการใช้คอมโพเนนต์เนื้อหาต่อไปในอนาคต