天天看點

​Flutter | 一個關于背景顔色引發的打臉慘案

起因

有個小夥伴在群裡問了這樣一個問題:

PopupMenuButton 怎麼改背景色?

這不正好撞槍口上了麼,剛寫完

PopupMenuButton

的文章,這個逼必須得裝。

​Flutter | 一個關于背景顔色引發的打臉慘案

趕緊去翻源碼,發現

PopupMenuButton

本身并沒有提供改變顔色的參數,

那沒辦法了,隻能找彈出頁面的源碼了。

找了半天找到了傳回彈出框的地方,加了一個

Container

,設定了一個 color,大功告成!

于是,我發了這樣的文字:

popup_menu.dart 466行,加個 Container 設定一下顔色就行了

功成身退!

​Flutter | 一個關于背景顔色引發的打臉慘案

本以為該群友會發出這樣的感歎:

哇,大佬牛逼牛逼!

如何如何...

然而,命運多舛,裝逼的道路總是這麼坎坷。不然我也不會寫這篇文章了。

另一個群友這樣說到:

他:「不能用 Theme 來搞定這個事嗎?」

我:「不能,它沒根據 Theme 來設定顔色,你可以翻源碼看一下。」

他:「圖檔 + 連結」

我(内心 OS):「卧槽,裝逼失敗了?趕緊去看看什麼情況!」

經過

打開連結,看到是用

Theme

包裹住

PopupMenuButton

,然後定義了一個

cardColor

,這是什麼操作?

我趕緊去試了試:

Theme(  data: ThemeData(cardColor: Colors.red),  child: PopupMenuButton<WhyFarther>(    // ...  ), ),           

複制

直接在上次的代碼中加入了一個 Theme,并且設定顔色為紅色。

調試啟動!

​Flutter | 一個關于背景顔色引發的打臉慘案

emmmmmmmmmm,

​Flutter | 一個關于背景顔色引發的打臉慘案

那麼這個時候問題來了,

cardColor

是個什麼玩意?

ThemeData

我們都知道,可以定義 Theme 來控制全局的顔色文字之類的,但是我從來不知道有個

cardColor

找資料!

功夫不負有心人,讓我找到了 簡書大佬「Magician」寫的 「Flutter:Theme」[1],

大佬翻譯了一下 ThemeData 的主要屬性,其中就包括

cardColor

:

cardColor -

Color

類型,

Material

被用作

Card

時的顔色。

什麼亂七八糟的,

Material

被用作

Card

當時我就氣不打一處來,我看了半天源碼,也沒見哪個 build 傳回了 Card!

沒辦法,全局搜尋 card 關鍵字!總能看出來問題!

Material

終于在我的不懈努力查找下,找到了可疑之處:

return Opacity(  opacity: opacity.evaluate(route.animation),  child: Material(    type: MaterialType.card,    /// ...    ),  ),);           

複制

這個

Material

元件下有個

type

參數,該參數竟然定義為了一個

MaterialType.card

不是你還能是誰!

這回終于了解了上述文字:

cardColor -

Color

類型,

Material

被用作

Card

時的顔色。

Material.type

你以為到這裡就結束了?不,我還要看一下這個 type 都有什麼類型:

enum MaterialType {  /// 使用預設主題畫布顔色的矩形。  canvas,
  /// 圓形邊緣,卡片主題顔色。  card,
  /// 預設情況下沒有顔色的圓(用于浮動操作按鈕)。  circle,
  /// 圓形邊緣,預設情況下沒有顔色(用于[MaterialButton]按鈕)。  button,
  /// 一塊透明的材料,用于繪制噴墨和高光。雖然材料隐喻描述了列印在材料本身上的子部件,但不隐藏墨迹效             果,但實際上[Material]小部件将子部件繪制在墨迹效果的頂部。具有類型透明度的[材質]可以放置在            不透明小部件的頂部,以在其頂部顯示墨迹效果。首選使用[ink]小部件在不透明小部件上顯示墨迹效果。  transparency}           

複制

不用猜了,上面中文都是我用翻譯軟體翻譯出來的!

那既然如此,我們改一下這個 type,把它改為

canvas

,看看還是不是紅色了:

​Flutter | 一個關于背景顔色引發的打臉慘案

總結

雖然裝逼失敗了,但是我個人對于 Theme 這方面的了解更深了,

而且以後如果有定義 Widget 的需求的話,也可以使用該方法,定義一個

Material

的 type,

這樣就可以和整個APP的風格保持一緻了。