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

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 นี้เสร็จได้ โดยใช้เวลาและลงแรงพอสมควร

เห็นด้วยอย่างยิ่ง เห็นด้วย เฉยๆ ไม่เห็นด้วย ไม่เห็นด้วยอย่างยิ่ง

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

เห็นด้วยอย่างยิ่ง เห็นด้วย เฉยๆ ไม่เห็นด้วย ไม่เห็นด้วยอย่างยิ่ง