1. FlutterComponent最佳實(shí)踐之色彩管理

        共 7124字,需瀏覽 15分鐘

         ·

        2022-03-03 21:51

        點(diǎn)擊上方藍(lán)字關(guān)注我,知識(shí)會(huì)給你力量


        Flutter中關(guān)于色彩和主題的內(nèi)容非常之多,我們需要理清不同的Color之間的異同,才能更好的開(kāi)發(fā)Flutter應(yīng)用。

        MaterialColor

        在ThemeData的構(gòu)造函數(shù)中,我們可以發(fā)現(xiàn)兩個(gè)很有意思的屬性

        MaterialColor? primarySwatch,
        Color? primaryColor,

        在Flutter創(chuàng)建的Demo中,Theme是這樣設(shè)置的。

        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );

        有沒(méi)有人很好奇,primarySwatch和primaryColor,到底要設(shè)置哪個(gè)?到底誰(shuí)才是真正的「主色調(diào)」?

        首先,MaterialColor并不等于Color,它是基于MaterialDesign而產(chǎn)生的一套顏色體系。

        material_design_color_system

        在這個(gè)顏色系統(tǒng)中,基色和明暗不同的10種顏色作為一組處理,從而形成了MaterialColor。

        前面代碼中的Colors.blue,實(shí)際上就是一個(gè)MaterialColor,我們來(lái)看下它的實(shí)現(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;

        由此可見(jiàn),MaterialColor的10種顏色是怎么實(shí)現(xiàn)的。

        事實(shí)上,MaterialColor的定義就是如此,一個(gè)基色,加上一個(gè)不同shade的Map。

        image-20220213131410151

        如果你要自定義一個(gè)MaterialColor,那么這10種色調(diào),也是必須要實(shí)現(xiàn)的。

        ?

        除了MaterialColor以外,還有一個(gè)MaterialAccentColor,它和MaterialColor類(lèi)似,但是只有5種色調(diào)。

        ?

        Color

        Colors:這個(gè)類(lèi)是來(lái)自Material調(diào)色板的顏色。要在代碼中訪問(wèn)它們,只需調(diào)用基色和shade值即可。

        color: Colors.red
        color: Colors.red[200]

        Color:你可以將這個(gè)類(lèi)用于Material調(diào)色板以外的顏色,因?yàn)樗试SARGB(Alpha, Red, Green, Blue)格式的顏色值。最常見(jiàn)的使用方法是像下面的代碼這樣傳遞十六進(jìn)制顏色代碼,其中0xFF代表完全不透明的顏色。

        Color(0xFF42A5F5)

        primarySwatch

        接下來(lái),我們繼續(xù)來(lái)看前面提到的那個(gè)問(wèn)題,為什么ThemeData中需要設(shè)置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中設(shè)不設(shè)置primarySwatch都會(huì)是藍(lán)色的主題色的原因了。

        那么一個(gè)具體的Flutter組件,是如何決定自己的主題的呢?以Appbar為例,我們?cè)谠创a中找到對(duì)應(yīng)設(shè)置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,
            );
        ?

        不要被這里茫茫多的問(wèn)號(hào)搞昏了,復(fù)習(xí)一下Dart語(yǔ)法吧。

        • 「?.」——代表非空訪問(wèn),例如「myObject?.someProperty」,等價(jià)于——「(myObject != null) ? myObject.someProperty : null」
        • 「??」——代表避空判斷,例如「a ?? 3」a為空時(shí),返回3
        • 「??=」——同樣是避空賦值,例如「a ??= 3」a為空時(shí),a賦值為3
        ?

        了解了這些之后,你應(yīng)該就能看懂上面的代碼了,原來(lái)Appbar的background是經(jīng)過(guò)很多場(chǎng)景來(lái)判斷的,簡(jiǎn)而言之:

        • 先判斷是否在Appbar中設(shè)置了backgroundColor
        • 再判斷是否指定了AppBarTheme.backgroundColor,也就是針對(duì)Appbar進(jìn)行的Theme覆蓋
        • 最后再根據(jù)是否黑夜模式來(lái)判斷使用ColorScheme.primary還是ColorScheme.surface

        大部分的Flutter組件,幾乎都遵循這個(gè)判斷流程,只是使用的Color類(lèi)型不太一樣。

        但是,primaryColor并不是沒(méi)用了,它可以用來(lái)更改組件的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

        色彩的千變?nèi)f化,最終會(huì)導(dǎo)致Theme屬性的膨脹,這是可以預(yù)見(jiàn)的,所以你可以看看ThemeData有多少屬性需要配置就知道了。

        在ThemeData的構(gòu)造函數(shù)中,有超過(guò)70種的Color和Theme,這要全部通過(guò)手工來(lái)配置,將是一個(gè)非常大的工作量。

        因此,F(xiàn)lutter引入了ColorScheme屬性,它是一組基于Material規(guī)范的25種顏色(9種必選色),可用于配置大多數(shù)組件的顏色屬性。Flutter團(tuán)隊(duì)計(jì)劃用定義好的ColorScheme來(lái)設(shè)計(jì)材質(zhì)組件的樣式。要使用colorScheme,你必須調(diào)用ThemeData.from()構(gòu)造函數(shù)。

        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只需要給對(duì)應(yīng)的屬性填上不同的色值即可。

        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方法,讓開(kāi)發(fā)者可以根據(jù)一個(gè)基色來(lái)生成符合Material Design規(guī)范的ColorScheme。

        ?

        MaterialDesign提供了ThemeBuilder來(lái)幫助開(kāi)發(fā)者創(chuàng)建這些代碼。

        https://material-foundation.github.io/material-theme-builder/#/custom

        下面這張圖,就展示了Flutter中不同的Color之間的關(guān)系。

        img

        向大家推薦下我的網(wǎng)站 https://xuyisheng.top/  點(diǎn)擊原文一鍵直達(dá)

        專(zhuān)注 Android-Kotlin-Flutter 歡迎大家訪問(wèn)



        往期推薦


        本文原創(chuàng)公眾號(hào):群英傳,授權(quán)轉(zhuǎn)載請(qǐng)聯(lián)系微信(Tomcat_xu),授權(quán)后,請(qǐng)?jiān)谠瓌?chuàng)發(fā)表24小時(shí)后轉(zhuǎn)載。
        < END >
        作者:徐宜生

        更文不易,點(diǎn)個(gè)“三連”支持一下??


        瀏覽 70
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 亚洲第一天堂久久 | 精品欧美一区二区在线观看 | 人妻无码中文字幕免费蜜桃 | 久久久久中文字幕亚洲精品 | 做受 视频毛片丰满 |