用抽象工廠方法構建 Flutter 主題

語言: CN / TW / HK

老鐵記得 轉發 ,貓哥會呈現更多 Flutter 好文~~~~

微信群 ducafecat

b 站 https://space.bilibili.com/404904528

原文

https://vbacik-10.medium.com/flutter-build-theme-with-abstract-factory-method-e07df8f730e2

程式碼

https://github.com/VB10/flutter-abstract-theme-manager

參考

  • https://zeplin.io

正文

最多的應用程式至少建立了一個主題。也許這對於第一個版本來說已經足夠了,但是如果這個專案繼續增長呢?讓我們來看看怎麼做。

我們知道專案設計的主題有多重要,所以我們將為專案建立一個主題管理器。讓我們建立一個主題管理器以及這個購物頁面。

  • 設計稿 https://adobe.ly/xdfreshfooduikit

首先,它需要一個頁面設計,如也這個頁面可以連線到服務。(我為這個示例頁面建立了這個端點)

  • Background 背景
  • App bar - 應用程式欄
  • Search Bar - 搜尋欄 — Search Icon ー搜尋圖示 — Search Text ー搜尋文字 — Microphone Icon ー麥克風圖示
  • ListView — Product Card ー產品卡
  • TabBar — TabBar Icons ー TabBar 圖示集

因此,我們需要一個調色盤使用這個專案。如果你的設計工具包有一個調色盤,你可以在設計工具包中得到所有的顏色。

專案必須在需要新小部件時使用這個調色盤。實際上,由於有了主題經理,專案會更容易成長。最後,我們準備好了 Hacking 時間,因此我們將同時使用工廠方法模式和頁面原子設計。

Hacking Time

首先,我更喜歡先寫核心特性,這就是為什麼我們不會在程式碼完成時加倍工作的原因:

  • 使用不同顏色和樣式的 ITheme 抽象類
  • 用於從一個點管理不同主題的 ThemeFactory 類

工廠設計是創新模式之一。這個模式提供了高階物件,因為客戶機什麼都不知道。現在,該模式建立了一個自定義物件,以便專案可以使用這個方案。

現在我們知道了這個結構需要什麼,因為我們可以編寫一個同時包含文字和顏色的介面。這個介面提供了一箇中心視點,因此專案需要。讓我們寫下這些要點。

文字主題介面

每個專案都需要這一點,因為大多數用法都指向專案的文字指南。所以我們建立基本樣式指南後,非常容易從檢視使用。有時我們需要自定義文字樣式並不意味著你不使用當前的樣式。我們可以使用 copyWith 函式,這樣就可以像 headline5 一樣使用檢視,也可以新增自定義屬性,如文字顏色。

```dart abstract class ITextTheme { final Color? primaryColor; late final TextTheme data; TextStyle? headline1; TextStyle? headline3; TextStyle? headline4; TextStyle? headline5; TextStyle? headline6; TextStyle? subtitle1; TextStyle? subtitle2; TextStyle? bodyText1; TextStyle? bodyText2; String? fontFamily;

ITextTheme(this.primaryColor); } ```

如果您的專案設計有一個工具包,您可以使用 zeplin 工具。這個工具在樣式指南選項卡中獲取所有的文字樣式。

https://zeplin.io/

顏色主題介面

指向專案是非常重要的,因為你知道顏色無處不在。所以我們如何管理更多的專案很容易控制。每個專案都有一個特定的顏色模式,您必須在程式碼中使用這個模式。如果你不使用模式和專案有一個靜態的顏色程式碼,你不會新增多主題選項,另外你不能管理顏色問題。

```dart abstract class IColors { _AppColors get colors; Color? scaffoldBackgroundColor; Color? appBarColor; Color? tabBarColor; Color? tabbarSelectedColor; Color? tabbarNormalColor; Brightness? brightness;

ColorScheme? colorScheme; } ```

我說像 paragraph 關於 zeplin。再次你可以使用這個和你能夠所有的顏色屬性。

Abstract Factory Manager

為多介面建立的管理器。此管理器將為專案建立 ThemeData 例項。由於這個介面,您可以建立一個新的主題例項。這個新的主題只需要一個配色方案等。

dart abstract class ITheme { ITextTheme get textTheme; IColors get colors; }

是的,它看起來很簡單,對任何專案都很有用。最後,我們準備使用核心主題繪製操作,因此專案可以宣告這個結構的自定義主題。也許,這些主題介面可以改進得更高階。現在對於這個專案來說已經足夠了。

最後需要工廠建立者和我們使用這個專案的主題管理器

dart abstract class ThemeManager { static ThemeData craeteTheme(ITheme theme) => ThemeData( fontFamily: theme.textTheme.fontFamily, textTheme: theme.textTheme.data, cardColor: theme.colors.colorScheme?.onSecondary, floatingActionButtonTheme: FloatingActionButtonThemeData( foregroundColor: theme.colors.colors.white, backgroundColor: theme.colors.colors.green), appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor), scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor, colorScheme: theme.colors.colorScheme); }

我計劃只有具體的領域,因為它的專案只有兩個頁面,因為你知道這個樣本。你必須建立文字樣式和配色方案區域的其他區域。讓我們用這個結構建立自定義主題,我們將展示這種使用優勢。

Ligh Theme on Project

實際上,我們有一個結構和專案,如何建立一個輕的主題。

```dart class AppThemeLight extends ITheme { @override late final ITextTheme textTheme;

AppThemeLight() { textTheme = TextThemeLight(colors.colors.mediumGrey); }

@override IColors get colors => LightColors(); } ```

當然,暗主題建立這樣,因此只是改變風格的指導方針和專案可以直接使用。您可以在這裡訪問黑暗主題程式碼。

TextTheme Light 需要繪製文字預設顏色的基本顏色,而淺色已經從 zeplin 樣式建立。

```dart class TextThemeLight implements ITextTheme { @override late final TextTheme data;

@override TextStyle? bodyText1;

@override TextStyle? bodyText2;

@override TextStyle? headline1;

@override TextStyle? headline3;

@override TextStyle? headline4;

@override TextStyle? headline5;

@override TextStyle? headline6;

@override TextStyle? subtitle1;

@override TextStyle? subtitle2; final Color? primaryColor;

TextThemeLight(this.primaryColor) { data = TextTheme( headline6: TextStyle(fontSize: 20, fontWeight: FontWeight.normal), subtitle1: TextStyle(fontSize: 16.0), ).apply(bodyColor: primaryColor); fontFamily = GoogleFonts.arvo().fontFamily; }

@override String? fontFamily; } ```

好的,如果我們想看淺色的主題例項,它顯示了這一點。

```dart class LightColors implements IColors { @override final _AppColors colors = _AppColors();

@override ColorScheme? colorScheme; @override Color? appBarColor;

@override Color? scaffoldBackgroundColor;

@override Color? tabBarColor;

@override Color? tabbarNormalColor;

@override Color? tabbarSelectedColor;

LightColors() { appBarColor = colors.white; scaffoldBackgroundColor = colors.white; tabBarColor = colors.green; tabbarNormalColor = colors.lighterGrey; tabbarSelectedColor = colors.darkerGrey; colorScheme = ColorScheme.light() .copyWith(onPrimary: colors.green, onSecondary: colors.white); brightness = Brightness.light; }

@override Brightness? brightness; } ```

有時需要準備風格,因為沒有足夠的風格知識。這時你可以為你的專案使用一個配色方案例項,這樣你就可以得到材質配色方案,因此可以新增你自定義的業務層。

而 Light 主題就是準備使用的。該專案只需要主題工廠方法,您可以編寫這個類例項。對於專案顏色的所有內容,這都是可以接受的。

dart class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '@VB10', theme: ThemeManager.craeteTheme(AppThemeLight()), home: SampleView(), ); } }

是的,我們可以開始在搜尋結果螢幕上繪圖。特別是不要忘記這個方法,讓我們看看如何為這個專案建立一個主題例項。

dart abstract class ThemeManager { static ThemeData craeteTheme(ITheme theme) => ThemeData( fontFamily: theme.textTheme.fontFamily, textTheme: theme.textTheme.data, cardColor: theme.colors.colorScheme?.onSecondary, tabBarTheme: TabBarTheme( indicator: BoxDecoration(), labelColor: theme.colors.tabbarSelectedColor, unselectedLabelColor: theme.colors.tabbarNormalColor, ), floatingActionButtonTheme: FloatingActionButtonThemeData( foregroundColor: theme.colors.colors.white, backgroundColor: theme.colors.colors.green), appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor), scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor, colorScheme: theme.colors.colorScheme); }

現在專案直接依賴於所有的主題例項,因為我們只是改變主題值後,這個專案去一個新的配色方案,另外專案從來不需要任何程式碼的設計時間。這一點意味著你的專案設計已經完成了所有的工作

Feature Page

我們有一個主題例項,所以只需呼叫這個例項,一切就緒。首先,繪製頁面樹非常重要,更好地理解。

現在編碼非常簡單,因為我們知道如何繪製這個。特別是您對編碼時間非常注意,因此可以在頁面設計中始終使用主題例項。該專案有一個主題設計,因為可以直接呼叫這個變數。例如,任何頁面可以需要背景色,所以我們不需要一遍又一遍地寫,因為我們有使用這種情況的主題例項。

是的,我們準備開發另外的主題管理器和小部件樹結構。首先,讓我們在編碼中建立一個 tab 檢視結構。

```dart final List> _pages = [ MapEntry(SampleView(), Icons.search), MapEntry(Container(), Icons.search), MapEntry(Container(), Icons.search), MapEntry(Container(), Icons.search), ];

@override Widget build(BuildContext context) { return DefaultTabController( length: _pages.length, child: Scaffold( floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButton: floatingActionButton(context), bottomNavigationBar: _bottomAppBar(), body: TabBarView(children: _pages.map((e) => e.key).toList()), )); } ```

實際上,我們看到了 fab 按鈕,我們需要一個自定義顏色,因為這個顏色是為藍色建立的,但是我們在主題中添加了這個自定義程式碼,只寫了一個浮動的操作按鈕。此按鈕從上下文中讀取主題例項中的 own 屬性。

我說你不需要額外的程式碼,直接呼叫這個小部件。

dart FloatingActionButton floatingActionButton(BuildContext context) { return FloatingActionButton( child: Icon(Icons.add), onPressed: () {}, ); }

之後,讓我們顯示搜尋結果頁面設計。我們談到了這篇頁面設計對文章的打擊。這對顫振計劃非常重要。你需要一直考慮這個樹型結構。你可以用這個小部件樹的思想做一個很棒的頁面。

dart @override Widget build(BuildContext context) { return Scaffold( appBar: buildAppBar(context), body: Padding( padding: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.08), child: Column( children: [ textFieldSearchCard(context), Expanded(child: buildGridViewBody()), ], ), ), ); }

這說明了很多問題。讓我們來看一些小部件,以瞭解如何使用主題。我們的設計有一個自定義搜尋欄,帶有搜尋圖示和麥克風按鈕。

dart Widget textFieldSearch(BuildContext context) { return TextField( decoration: InputDecoration( border: InputBorder.none, prefixIcon: Icon(Icons.search_sharp, color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.5)), suffixIconConstraints: BoxConstraints(maxHeight: 30), suffixIcon: FloatingActionButton( onPressed: () {}, mini: true, child: Icon(Icons.mic_sharp), )), ); }

這種程式碼設計不需要額外的程式碼。您可以從主題上下文中使用這裡需要的內容。讓我們來看看文字樣式示例:

dart Text buildTextSub(BuildContext context) { return Text( items.searchResults, style:Theme.of(context).textTheme.headline6?.copyWith( letterSpacing: -0.2, fontWeight: FontWeight.w400, ), ); }

你可以看到這是一個非常簡單和易於管理的程式碼,我只是添加了一些自定義程式碼並完成了所有的工作。

你可以看到條目屬性,也許這和註釋有重要的關係。如果您擁有所有的常量值類,並且只想建立常量值,那麼您可以在類獲得安全能力之後新增@immutable 註釋。

dart @immutable class AppTextItems { final String searchResults = 'Search Results'; final String brocoliText = 'Broccoli'; }

是的,這個專案可能是理解這個體系結構的一個樣本,但是總是應該編寫強大的程式碼。

Yees 專案已經完成。如果你想改變一個主題,比如黑暗,我們只需要把這個例項改成黑暗,然後就可以了。

因此,我們採用了抽象的工廠設計能力和可管理的程式碼設計。它聽起來很適合開發力量,因為顫振可以改善模式和特殊的角度。

完成了。現在我們可以直接實施我們自己的專案並管理一切。另一方面,這個專案不需要如何建立新的主題知識,因為你知道我們建立介面。不同的主題剛好適合這些介面,然後一切都完成了。

實際上,本文的主要目標是如何在主題例項中使用這種模式,因此這方面的知識對您的開發生活非常重要。

感謝你閱讀《感謝你閱讀《為你的生命健康》》

https://github.com/VB10/flutter-abstract-theme-manager


© 貓哥

https://ducafecat.tech/

https://github.com/ducafecat

往期

開源

GetX Quick Start

https://github.com/ducafecat/getx_quick_start

新聞客戶端

https://github.com/ducafecat/flutter_learn_news

strapi 手冊譯文

https://getstrapi.cn

微信討論群 ducafecat

系列集合

譯文

https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/

開源專案

https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/

Dart 程式語言基礎

https://space.bilibili.com/404904528/channel/detail?cid=111585

Flutter 零基礎入門

https://space.bilibili.com/404904528/channel/detail?cid=123470

Flutter 實戰從零開始 新聞客戶端

https://space.bilibili.com/404904528/channel/detail?cid=106755

Flutter 元件開發

https://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter Bloc

https://space.bilibili.com/404904528/channel/detail?cid=177519

Flutter Getx4

https://space.bilibili.com/404904528/channel/detail?cid=177514

Docker Yapi

https://space.bilibili.com/404904528/channel/detail?cid=130578