FlutterComponent最佳實踐之色彩管理
點擊上方藍字關注我,知識會給你力量
Flutter中關于色彩和主題的內容非常之多,我們需要理清不同的Color之間的異同,才能更好的開發(fā)Flutter應用。
MaterialColor
在ThemeData的構造函數中,我們可以發(fā)現(xiàn)兩個很有意思的屬性
MaterialColor? primarySwatch,
Color? primaryColor,
在Flutter創(chuàng)建的Demo中,Theme是這樣設置的。
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
有沒有人很好奇,primarySwatch和primaryColor,到底要設置哪個?到底誰才是真正的「主色調」?
首先,MaterialColor并不等于Color,它是基于MaterialDesign而產生的一套顏色體系。
在這個顏色系統(tǒng)中,基色和明暗不同的10種顏色作為一組處理,從而形成了MaterialColor。
前面代碼中的Colors.blue,實際上就是一個MaterialColor,我們來看下它的實現(xiàn)。
static const MaterialColor blue = MaterialColor(
_bluePrimaryValue,
<int, Color>{
50: Color(0xFFE3F2FD),
100: Color(0xFFBBDEFB),
200: Color(0xFF90CAF9),
300: Color(0xFF64B5F6),
400: Color(0xFF42A5F5),
500: Color(_bluePrimaryValue),
600: Color(0xFF1E88E5),
700: Color(0xFF1976D2),
800: Color(0xFF1565C0),
900: Color(0xFF0D47A1),
},
);
static const int _bluePrimaryValue = 0xFF2196F3;
由此可見,MaterialColor的10種顏色是怎么實現(xiàn)的。
事實上,MaterialColor的定義就是如此,一個基色,加上一個不同shade的Map。
如果你要自定義一個MaterialColor,那么這10種色調,也是必須要實現(xiàn)的。
?除了MaterialColor以外,還有一個MaterialAccentColor,它和MaterialColor類似,但是只有5種色調。
?
Color
Colors:這個類是來自Material調色板的顏色。要在代碼中訪問它們,只需調用基色和shade值即可。
color: Colors.red
color: Colors.red[200]
Color:你可以將這個類用于Material調色板以外的顏色,因為它允許ARGB(Alpha, Red, Green, Blue)格式的顏色值。最常見的使用方法是像下面的代碼這樣傳遞十六進制顏色代碼,其中0xFF代表完全不透明的顏色。
Color(0xFF42A5F5)
primarySwatch
接下來,我們繼續(xù)來看前面提到的那個問題,為什么ThemeData中需要設置primarySwatch。
在theme_data的源代碼中,我們可以發(fā)現(xiàn)這樣的代碼。
primarySwatch ??= Colors.blue;
primaryColor ??= isDark ? Colors.grey[900]! : primarySwatch;
final Brightness _primaryColorBrightness = estimateBrightnessForColor(primaryColor);
primaryColorLight ??= isDark ? Colors.grey[500]! : primarySwatch[100]!;
primaryColorDark ??= isDark ? Colors.black : primarySwatch[700]!;
從這里,我們就可以知道為什么在Demo中設不設置primarySwatch都會是藍色的主題色的原因了。
那么一個具體的Flutter組件,是如何決定自己的主題的呢?以Appbar為例,我們在源代碼中找到對應設置background的地方。
final Color backgroundColor = backwardsCompatibility
? widget.backgroundColor
?? appBarTheme.backgroundColor
?? theme.primaryColor
: _resolveColor(
states,
widget.backgroundColor,
appBarTheme.backgroundColor,
colorScheme.brightness == Brightness.dark ? colorScheme.surface : colorScheme.primary,
);
?不要被這里茫茫多的問號搞昏了,復習一下Dart語法吧。
?
「?.」——代表非空訪問,例如「myObject?.someProperty」,等價于——「(myObject != null) ? myObject.someProperty : null」 「??」——代表避空判斷,例如「a ?? 3」a為空時,返回3 「??=」——同樣是避空賦值,例如「a ??= 3」a為空時,a賦值為3
了解了這些之后,你應該就能看懂上面的代碼了,原來Appbar的background是經過很多場景來判斷的,簡而言之:
-
先判斷是否在Appbar中設置了backgroundColor -
再判斷是否指定了AppBarTheme.backgroundColor,也就是針對Appbar進行的Theme覆蓋 -
最后再根據是否黑夜模式來判斷使用ColorScheme.primary還是ColorScheme.surface
大部分的Flutter組件,幾乎都遵循這個判斷流程,只是使用的Color類型不太一樣。
但是,primaryColor并不是沒用了,它可以用來更改組件的Theme,用于局部主題的使用。
Expanded(
child: Theme(
data: Theme.of(context).copyWith(primaryColor: Colors.red),
child: Container(
padding: const EdgeInsets.all(15.0),
color: Theme.of(context).primaryColor,
child: Text(
'This Container overrides primaryColor',
style: Theme.of(context).headline5,
),
)))
ColorScheme
色彩的千變萬化,最終會導致Theme屬性的膨脹,這是可以預見的,所以你可以看看ThemeData有多少屬性需要配置就知道了。
在ThemeData的構造函數中,有超過70種的Color和Theme,這要全部通過手工來配置,將是一個非常大的工作量。
因此,F(xiàn)lutter引入了ColorScheme屬性,它是一組基于Material規(guī)范的25種顏色(9種必選色),可用于配置大多數組件的顏色屬性。Flutter團隊計劃用定義好的ColorScheme來設計材質組件的樣式。要使用colorScheme,你必須調用ThemeData.from()構造函數。
ThemeData.from(
colorScheme: const ColorScheme.light().copyWith(
primary: const Color(0xff455a64),
primaryContainer: const Color(0xff1c313a),
secondary: const Color(0xffffc400),
secondaryContainer: const Color(0xffc79400),
),
);
創(chuàng)建ColorScheme只需要給對應的屬性填上不同的色值即可。
ColorScheme colorScheme = ColorScheme(
brightness: isDark ? Brightness.dark : Brightness.light,
primary: accent1,
onPrimary: Colors.white,
secondary: accent1,
onSecondary: Colors.white,
error: Colors.red.shade400,
onError: Colors.red.shade400,
background: bg1,
onBackground: textColor,
surface: bg1,
onSurface: textColor,
);
?新版本的Flutter,還提供了fromSeed方法,讓開發(fā)者可以根據一個基色來生成符合Material Design規(guī)范的ColorScheme。
?
MaterialDesign提供了ThemeBuilder來幫助開發(fā)者創(chuàng)建這些代碼。
https://material-foundation.github.io/material-theme-builder/#/custom
下面這張圖,就展示了Flutter中不同的Color之間的關系。
向大家推薦下我的網站 https://xuyisheng.top/ 點擊原文一鍵直達
專注 Android-Kotlin-Flutter 歡迎大家訪問
往期推薦
更文不易,點個“三連”支持一下??
