Pembangunan Aplikasi Mudah Alih Flutter · Pelajaran

ThemeExtension Tersuai untuk Token Jenama

Takrif dan gunakan token reka bentuk tersuai dengan menulis kelas ThemeExtension.

Pelajaran 3 daripada 413 langkah

ThemeExtension Tersuai untuk Token Jenama ialah pelajaran Pembangunan Aplikasi Mudah Alih Flutter percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Pembangunan Aplikasi Mudah Alih Flutter, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Pembangunan Aplikasi Mudah Alih Flutter merangkumi sejumlah 4 pelajaran.

Mengapa Token Jenama Memerlukan Tempat

Material 3 memberikan anda ColorScheme yang kaya, tetapi produk sebenar mempunyai keputusan reka bentuk tambahan yang tidak sepadan dengan mana-mana slot terbina dalam: gradien jenama, warna berjaya, aksen promosi dan jejari kad tersuai.

Menetapkan semua ini sebagai pemalar global bermasalah sebaik sahaja anda menyokong mod cerah dan gelap, kerana satu pemalar tidak boleh berubah mengikut ThemeData yang aktif.

  • Anda mahu nilai ini berada di dalam tema.
  • Anda mahu nilai ini diinterpolasi dengan lancar semasa animasi tema.
  • Anda mahu membacanya dengan kemudahan penggunaan Theme.of(context) yang sama seperti segala-galanya.

Jawapan Flutter ialah ThemeExtension.

Apakah ThemeExtension

ThemeExtension<T> ialah class abstrak yang anda subkelas untuk melampirkan himpunan nilai bertip sendiri pada ThemeData.

Parameter generik T ialah class anda sendiri. Inilah yang membolehkan Flutter menyimpan dan mendapatkan semula extension anda berdasarkan jenis tepatnya, bukannya berdasarkan kunci rentetan.

  • Ia selamat dari segi jenis: tiada penukaran jenis daripada Map.
  • Ia peka tema: ia disertakan dalam ThemeData, jadi mod cerah dan gelap boleh mempunyai tika yang berbeza.
  • Ia menyokong animasi: Flutter memanggil lerp untuk menggabungkan dua tika apabila tema berubah.

Anda mesti melaksanakan dua method: copyWith dan lerp.

Mengisytiharkan Class Extension

Mulakan dengan mensubkelas ThemeExtension menggunakan class anda sebagai argumen jenis. Jadikan setiap medan final supaya tika tidak boleh diubah.

Di sini kita memodelkan palet jenama kecil: aksen promosi, warna berjaya dan gradien jenama.

import 'package:flutter/material.dart';

class BrandColors extends ThemeExtension<BrandColors> {
  const BrandColors({
    required this.accent,
    required this.success,
    required this.brandGradient,
  });

  final Color accent;
  final Color success;
  final Gradient brandGradient;

  @override
  ThemeExtension<BrandColors> copyWith({
    Color? accent,
    Color? success,
    Gradient? brandGradient,
  }) {
    return BrandColors(
      accent: accent ?? this.accent,
      success: success ?? this.success,
      brandGradient: brandGradient ?? this.brandGradient,
    );
  }
}

Melaksanakan copyWith

copyWith mengembalikan tika baharu dengan sesetengah medan digantikan. Coraknya sentiasa sama: setiap parameter boleh bernilai null, dan anda menggunakan this.field sebagai sandaran apabila pemanggil menghantar null.

  • Ia mengekalkan class tidak boleh ubah — anda tidak pernah mengubahnya, sebaliknya mengklonkannya bersama perubahan.
  • Inilah cara pengguna melaraskan satu token tanpa membina semula keseluruhan objek.

Perhatikan bahawa jenis pulangan ialah ThemeExtension<BrandColors>, sepadan dengan tandatangan abstrak, walaupun anda membina BrandColors yang konkrit.

Melaksanakan lerp untuk Peralihan Lancar

lerp (interpolasi linear) menggabungkan this ke arah tika lain dengan faktor t antara 0.0 dan 1.0. Flutter memanggilnya semasa animasi tema supaya token tersuai anda berubah secara beransur-ansur selancar token terbina dalam.

Gunakan pembantu statik yang disediakan oleh setiap jenis: Color.lerp dan Gradient.lerp. Kendalikan keadaan apabila other ialah jenis extension yang berbeza dengan mengembalikan this.

@override
ThemeExtension<BrandColors> lerp(
  covariant ThemeExtension<BrandColors>? other,
  double t,
) {
  if (other is! BrandColors) {
    return this;
  }
  return BrandColors(
    accent: Color.lerp(accent, other.accent, t)!,
    success: Color.lerp(success, other.success, t)!,
    brandGradient: Gradient.lerp(brandGradient, other.brandGradient, t)!,
  );
}

Mentakrifkan Tika Cerah dan Gelap

Oleh sebab extension berada di dalam ThemeData, anda mencipta satu tika yang ditala untuk mod cerah dan satu lagi untuk mod gelap. Dedahkan tika tersebut sebagai static const (atau static final apabila nilai tidak boleh dibina sebagai const) pada class supaya mudah dirujuk.

Inilah kelebihan berbanding pemalar global: nama token yang sama menghasilkan nilai yang berbeza bergantung pada tema yang aktif.

class BrandColors extends ThemeExtension<BrandColors> {
  // ...constructor, fields, copyWith, lerp as before...

  static const light = BrandColors(
    accent: Color(0xFFFF6D00),
    success: Color(0xFF2E7D32),
    brandGradient: LinearGradient(
      colors: [Color(0xFFFF6D00), Color(0xFFFFAB40)],
    ),
  );

  static const dark = BrandColors(
    accent: Color(0xFFFFAB40),
    success: Color(0xFF66BB6A),
    brandGradient: LinearGradient(
      colors: [Color(0xFFFFAB40), Color(0xFFFFD180)],
    ),
  );
}

Mendaftarkan Extension pada ThemeData

Pasangkan tika melalui parameter extensions bagi ThemeData. Parameter ini menerima Iterable extension; Flutter mengindeksnya berdasarkan jenis masa jalan.

Berikan tika cerah kepada ThemeData cerah dan tika gelap kepada ThemeData gelap supaya kedua-duanya bertukar secara automatik mengikut kecerahan platform.

MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
    extensions: const [BrandColors.light],
  ),
  darkTheme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.deepPurple,
      brightness: Brightness.dark,
    ),
    extensions: const [BrandColors.dark],
  ),
  home: const HomePage(),
);

Menggunakan Extension dalam Widget

Baca extension anda dengan Theme.of(context).extension<BrandColors>(). Argumen jenis generik menjadi kunci carian dan mengembalikan BrandColors? yang boleh bernilai null.

Selepas mendapatkan tika tersebut, setiap token ialah medan bertip biasa — tiada penukaran jenis dan pelengkapan automatik sepenuhnya.

class PromoBanner extends StatelessWidget {
  const PromoBanner({super.key});

  @override
  Widget build(BuildContext context) {
    final brand = Theme.of(context).extension<BrandColors>()!;
    return Container(
      decoration: BoxDecoration(
        gradient: brand.brandGradient,
        borderRadius: BorderRadius.circular(16),
      ),
      padding: const EdgeInsets.all(16),
      child: Text(
        'Limited offer',
        style: TextStyle(color: brand.accent),
      ),
    );
  }
}

Extension Penggunaan yang Kemas

Memanggil Theme.of(context).extension<BrandColors>()! di merata tempat agak berlebihan. Id iom yang biasa digunakan ialah menambah extension BuildContext kecil yang menyembunyikan carian di sebalik getter.

  • Ia memusatkan penegasan bukan-null di satu tempat.
  • Tapak panggilan menjadi kemas: context.brand.accent.
extension BrandThemeX on BuildContext {
  BrandColors get brand =>
      Theme.of(this).extension<BrandColors>()!;
}

// Usage inside any build method:
// final color = context.brand.success;

Model Mental lerp dalam Dart Tulen

Anda boleh memahami lerp tanpa Flutter. Interpolasi hanyalah a + (b - a) * t yang digunakan pada setiap saluran. Petikan di bawah menggabungkan dua integer dengan cara yang sama seperti Color.lerp menggabungkan setiap saluran ARGB.

Apabila dijalankan, contoh ini menunjukkan bahawa t = 0 menghasilkan nilai mula, t = 1 menghasilkan nilai akhir, dan t = 0.5 menghasilkan titik tengah — iaitu tingkah laku tepat yang menjadi sandaran animasi tema anda.

int lerpInt(int a, int b, double t) {
  return (a + (b - a) * t).round();
}

void main() {
  const start = 0; // think: red channel of color A
  const end = 200; // red channel of color B
  for (final t in [0.0, 0.25, 0.5, 0.75, 1.0]) {
    print('t=$t -> ${lerpInt(start, end, t)}');
  }
}

Berbilang Extension dan Perangkap Lazim

Anda boleh mendaftarkan beberapa extension bersebelahan — contohnya BrandColors dan BrandShapes yang berasingan untuk jejari dan jarak. Flutter menggunakan jenis masing-masing sebagai kunci, jadi kedua-duanya tidak pernah bertembung.

  • Terlupa mendaftar: extension<BrandColors>() mengembalikan null jika anda tidak pernah menambahkannya pada ThemeData.extensions; ! kemudiannya menghasilkan ralat.
  • Melangkau lerp: jika lerp hanya mengembalikan this, peralihan tema berubah secara mendadak dan bukannya beransur-ansur.
  • Argumen jenis yang salah: jenis dalam extension<T>() mesti sepadan tepat dengan class yang didaftarkan.
ThemeData(
  extensions: const [
    BrandColors.light,
    BrandShapes.standard,
  ],
);

// Look each one up independently:
// final brand = Theme.of(context).extension<BrandColors>()!;
// final shapes = Theme.of(context).extension<BrandShapes>()!;

Semakan Pantas

Anda telah menambah BrandColors pada ThemeData cerah dan gelap, dan kini menganimasikan peralihan antara kedua-duanya. Warna accent jenama berubah secara mendadak dan bukannya pudar dengan lancar. Kesilapan manakah yang paling berkemungkinan menyebabkannya?

Imbas Kembali

Kini anda mempunyai aliran kerja penetapan tema tersuai yang lengkap dalam Flutter:

  • Subkelas ThemeExtension<T> dengan medan final untuk token jenama anda.
  • Laksanakan copyWith (parameter boleh-null, gunakan this.field sebagai sandaran) dan lerp (gunakan Color.lerp, Gradient.lerp serta kendalikan jenis).
  • Bina tika light dan dark yang berbeza, kemudian daftarkannya melalui ThemeData.extensions.
  • Gunakan melalui Theme.of(context).extension<BrandColors>(), sebaik-baiknya dibungkus dalam getter context.brand.

Hasilnya: token reka bentuk khusus jenama yang selamat dari segi jenis, peka mod dan beranimasi dengan lancar — sama seperti ColorScheme terbina dalam Material 3.

Percuma untuk bermula

Pelajari Dart dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
22
Pelajaran
88

Soalan Lazim

Adakah pelajaran “ThemeExtension Tersuai untuk Token Jenama” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Pembangunan Aplikasi Mudah Alih Flutter, termasuk “ThemeExtension Tersuai untuk Token Jenama”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Pembangunan Aplikasi Mudah Alih Flutter merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “ThemeExtension Tersuai untuk Token Jenama”?

Takrif dan gunakan token reka bentuk tersuai dengan menulis kelas ThemeExtension. Anda berlatih Pembangunan Aplikasi Mudah Alih Flutter menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Pembangunan Aplikasi Mudah Alih Flutter?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Pembangunan Aplikasi Mudah Alih Flutter di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “ThemeExtension Tersuai untuk Token Jenama” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Pembangunan Aplikasi Mudah Alih Flutter ini?

Ya. Setiap pelajaran Pembangunan Aplikasi Mudah Alih Flutter menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Skema Warna Material 3 dan Warna Benih
  2. Warna Dinamik dan Tema Cerah/Gelap Adaptif
  3. ThemeExtension Tersuai untuk Token Jenama
  4. Tipografi Responsif dan Tema Komponen
← Kembali ke Pembangunan Aplikasi Mudah Alih Flutter