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

1. บทนำ

logo_components_color_2x_web_96dp.png

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

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

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

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

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

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

Android

iOS

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

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

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

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

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

คุณจะให้คะแนนระดับประสบการณ์ในการพัฒนาแอปด้วย Flutter เท่าไร

ผู้ฝึกหัด ขั้นกลาง ผู้ชำนาญ

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

คุณต้องมีซอฟต์แวร์ 2 อย่างเพื่อทำแล็บนี้ให้เสร็จสมบูรณ์ ได้แก่ Flutter SDK และโปรแกรมแก้ไข

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

  • อุปกรณ์ Android หรือ iOS จริงที่เชื่อมต่อกับคอมพิวเตอร์และตั้งค่าเป็นโหมดนักพัฒนาแอป
  • โปรแกรมจำลอง iOS (ต้องติดตั้งเครื่องมือ Xcode)
  • Android Emulator (ต้องตั้งค่าใน 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

หากต้องการโคลนโค้ดแล็บนี้จาก 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

หน้าเข้าสู่ระบบ Shrine ที่ไม่มีธีม

หน้าเข้าสู่ระบบ Shrine ที่ไม่มีธีม

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

Android

iOS

หน้าตารางกริดผลิตภัณฑ์ของ Shrine ที่ไม่มีธีม

หน้าตารางผลิตภัณฑ์ของ Shrine ที่ไม่มีธีม

4. เปลี่ยนสี

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

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

สร้าง colors.dart

สร้างไฟล์ 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 Theme Editor ซึ่งได้ขยายสีเหล่านั้นเพื่อสร้างชุดสีที่สมบูรณ์ยิ่งขึ้น (สีเหล่านี้ไม่ได้มาจากชุดสี Material ปี 2014)

Material Theme Editor ได้จัดระเบียบสีเหล่านี้เป็นเฉดสีที่มีป้ายกำกับเป็นตัวเลข รวมถึงป้ายกำกับ 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

หน้าเข้าสู่ระบบของ Shrine ที่มีธีมสีชมพูและสีน้ำตาล

หน้าเข้าสู่ระบบของ Shrine ที่มีธีมสีชมพูและสีน้ำตาล

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

นอกจากจะเปลี่ยนสีแล้ว นักออกแบบยังให้เราใช้ตัวอักษรเฉพาะด้วย ThemeData ของ Flutter มีธีมข้อความ 3 แบบ ธีมข้อความแต่ละธีมคือชุดรูปแบบข้อความ เช่น "บรรทัดแรก" และ "ชื่อ" เราจะใช้รูปแบบ 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

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

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

คุณอาจได้รับข้อผิดพลาดในการเรียกใช้ pub get หากคัดลอกและวางประกาศด้านบน หากพบข้อผิดพลาด ให้เริ่มด้วยการนำช่องว่างนำหน้าออกและแทนที่ด้วยช่องว่างโดยใช้การเยื้อง 2 ช่องว่าง (เว้น 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() (พาดหัว ชื่อ คำบรรยาย) เท่านั้น

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

ใช้ธีมข้อความใหม่

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

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

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

Android

iOS

หน้าตารางผลิตภัณฑ์ของ Shrine ที่ใช้ธีมข้อความ

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

ย่อข้อความ

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

ใน 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

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

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

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

จัดรูปแบบช่องข้อความ

นอกจากนี้ คุณยังกำหนดธีมการตกแต่งในช่องข้อความด้วย 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

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

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

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

ใน 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

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

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

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

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

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

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

ใน login.dart ให้เพิ่มค่า style: ลงใน NEXT ElevatedButton ดังนี้

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

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

Android

iOS

หน้าเข้าสู่ระบบของ Shrine ที่มีปุ่มถัดไปที่ยกระดับ

หน้าเข้าสู่ระบบของ Shrine ที่มีปุ่มถัดไปที่ยกระดับ

ปรับการแสดงการ์ด

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

ใน home.dart ให้เพิ่มค่า elevation: ลงในบัตร

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

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

Android

iOS

หน้าตารางผลิตภัณฑ์ Shrine ที่ไม่มีการยกระดับสำหรับการ์ดแต่ละใบ

หน้าตารางผลิตภัณฑ์ Shrine ที่ไม่มีการยกระดับสำหรับการ์ดแต่ละใบ

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

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

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

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

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

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

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

ตอนนี้ผลิตภัณฑ์จะเลื่อนในแนวนอนในรูปแบบที่ได้แรงบันดาลใจจากการถักทอ

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

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

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

Android

iOS

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

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

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

10. ยินดีด้วย

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

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

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

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

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

ฉันทำ Codelab นี้เสร็จได้โดยใช้เวลาและความพยายามที่สมเหตุสมผล

เห็นด้วยอย่างยิ่ง เห็นด้วย เป็นกลาง ไม่เห็นด้วย ไม่เห็นด้วยอย่างยิ่ง

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

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