<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          FlutterComponent最佳實踐之色彩管理

          共 7124字,需瀏覽 15分鐘

           ·

          2022-03-03 21:51

          點擊上方藍字關注我,知識會給你力量


          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而產生的一套顏色體系。

          material_design_color_system

          在這個顏色系統(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。

          image-20220213131410151

          如果你要自定義一個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之間的關系。

          img

          向大家推薦下我的網站 https://xuyisheng.top/  點擊原文一鍵直達

          專注 Android-Kotlin-Flutter 歡迎大家訪問



          往期推薦


          本文原創(chuàng)公眾號:群英傳,授權轉載請聯(lián)系微信(Tomcat_xu),授權后,請在原創(chuàng)發(fā)表24小時后轉載。
          < END >
          作者:徐宜生

          更文不易,點個“三連”支持一下??


          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品福利免费在线观看 | AV在线一区二区三区 | 黑人大香蕉伊人 | 粉嫩99精品99久久久久久桃色 | 91视频强奸乱伦家庭国产 |