Flutter實(shí)現(xiàn)一個(gè)支持漸變背景的Button示例詳解
Flutter中的按鈕
自Flutter 1.20 新增了ButtonStyleButton 系列按鈕,可以說(shuō)非常好用了,默認(rèn)樣式比之前漂亮了許多,擴(kuò)展性也增加了很多。按鈕樣式統(tǒng)一由ButtonStyle這個(gè)類(lèi)提供,支持根據(jù)各種狀態(tài)(MaterialState)變化的屬性,也增強(qiáng)了桌面平臺(tái)也友好性。
| 值 | 狀態(tài) |
|---|---|
| hovered | 鼠標(biāo)滑入 |
| focused | 焦點(diǎn) |
| pressed | 按下 |
| dragged | 拖動(dòng) |
| selected | 選中 |
| scrolledUnder | 與滾動(dòng)內(nèi)容疊加 |
| disabled | 不可用 |
| error | 錯(cuò)誤 |
最常用到的就是pressed和disabled還有桌面端的hovered。
可變化的屬性
| 屬性 | 說(shuō)明 | 備注 |
|---|---|---|
| backgroundColor | 背景色 | Flutter3.3版本之前對(duì)應(yīng) primary或onPrimary |
| foregroundColor | 前景色(文本顏色) | Flutter3.3版本之前對(duì)應(yīng) primary或onPrimary |
| elevation | 模擬物理深度 | 其實(shí)就是陰影淺重 |
| fixedSize | 按鈕尺寸 | 受最大尺寸和最小尺寸和布局影響 |
| maxinumSize | 最大尺寸 | |
| minimumSize | 最小尺寸 | |
| mouseCursor | 鼠標(biāo)圖標(biāo) | |
| overlayColor | 高亮色 | |
| padding | 內(nèi)容邊距 | |
| shadowColor | 陰影顏色 | |
| shape | 按鈕形狀 | 由OutlinedBorder定義 |
| side | 邊框樣式 | |
| surfaceTintColor | Material3使用的材質(zhì)顏色 | |
| textStyle | 文本樣式 |
可以看到默認(rèn)按鈕樣式,主要針對(duì)的是形狀,顏色和交互效果(overlay splash),普通情況下也夠用的。
不完美的地方
但是,要想進(jìn)一步定制按鈕效果,比如設(shè)計(jì)師提供的按鈕,是漸變色的,那怎么辦呢? 比較常見(jiàn)的做法是用Container自己寫(xiě)一個(gè)按鈕出來(lái)。Container的decoration可以說(shuō)非常好用了,支持單色,漸變,以及裝飾圖。AnimatedContainer還能對(duì)各種屬性做動(dòng)畫(huà)展現(xiàn)。
但是 按鈕要做的事情,不止是一個(gè)背景這么簡(jiǎn)單。比如上面提到的狀態(tài),以及點(diǎn)擊反饋,語(yǔ)義化等等。要使用Container把這一整套實(shí)現(xiàn)出來(lái),會(huì)非常繁瑣。
在child中處理
Button的child可以是任何Widget,那么,把Container放到child里來(lái)實(shí)現(xiàn)定制背景怎樣呢?且不說(shuō)Button默認(rèn)的padding之類(lèi)的,Button的效果,都是在背景層實(shí)現(xiàn)的,child中的任何可見(jiàn)元素,都會(huì)覆蓋在這層背景之上。簡(jiǎn)單來(lái)說(shuō),就是覆蓋背景的同時(shí)會(huì)覆蓋掉Button的Splash等overlay效果。
外面套一個(gè)wrapper
把Button套進(jìn)Container里,在Container的decoration中做背景。這個(gè)方法首先要做的就是把Button的背景和陰影去除,那么除了在Container里做背景,還要模擬出Button的陰影。
AnimatedContainer(
duration: Duration(milliseconds:200),
width: width,
height: height,
transformAlignment: Alignment.center,
clipBehavior: clipBehavior,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue,Colors.red]
),
shadow: [BoxShadow(
...
)]
),
child: ElevatedButton(
//...
),
);初步來(lái)看,這個(gè)方法還是可行的。重點(diǎn)就在于怎么把需要增強(qiáng)的屬性組織起來(lái),并且和按鈕的狀態(tài)結(jié)合起來(lái)了。
MaterialStateProperty
按鈕的動(dòng)態(tài)屬性,都是基于這個(gè)狀態(tài)屬性處理的,它可以根據(jù)當(dāng)前的屬性集合,匹配到合適的屬性提供回來(lái)。
MaterialStatesController
按鈕狀態(tài)的控制器,可以通過(guò)這個(gè)控制器來(lái)監(jiān)聽(tīng)按鈕的狀態(tài),做出對(duì)應(yīng)處理
邊距問(wèn)題
ButtonStyle中有一個(gè)tapTargetSize屬性(非動(dòng)態(tài)屬性),定義了點(diǎn)擊目標(biāo)的擴(kuò)展邊距,在移動(dòng)設(shè)備上默認(rèn)情況下按鈕會(huì)向上/下多出一點(diǎn)邊距,導(dǎo)致Container的背景比按鈕尺寸多出一塊,按鈕的overlay效果鋪不滿(mǎn),手動(dòng)指定TapTargetSize.shrinkWrap就可以了。
EnhancedButton
結(jié)合以上想法,整理了style及wrapper實(shí)現(xiàn)了一個(gè)增加的按鈕,效果如下

本來(lái)命名的ExtendedButton,結(jié)果被一個(gè)不維護(hù)的包占用了名字,就改成了EnhancedButton。雖然目前還有些許不完美的方面,以后再慢慢優(yōu)化吧。
github: github.com/shirne/exte…
pub: pub.flutter-io.cn/packages/en…
以上就是Flutter實(shí)現(xiàn)一個(gè)支持漸變背景的Button示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutte 漸變背景 Button的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android中Rxjava實(shí)現(xiàn)三級(jí)緩存的兩種方式
這篇文章主要介紹了Android中Rxjava實(shí)現(xiàn)三級(jí)緩存的兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Android11及以上文件讀寫(xiě)權(quán)限申請(qǐng)?jiān)敿?xì)介紹
安卓11改變了此前安卓系統(tǒng)對(duì)于文件管理的規(guī)則,在安卓 11 上,文件讀寫(xiě)變成了特殊權(quán)限,下面這篇文章主要給大家介紹了關(guān)于Android11及以上文件讀寫(xiě)權(quán)限申請(qǐng)的相關(guān)資料,需要的朋友可以參考下2022-08-08
Android 獲取正在運(yùn)行的任務(wù)和服務(wù)的小例子
Android 獲取正在運(yùn)行的任務(wù)和服務(wù)的小例子,需要的朋友可以參考一下2013-05-05
Android采用消息推送實(shí)現(xiàn)類(lèi)似微信視頻接聽(tīng)
這篇文章主要為大家詳細(xì)介紹了Android采用消息推送實(shí)現(xiàn)類(lèi)似微信視頻接聽(tīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
android 字體顏色選擇器(ColorPicker)介紹
本文將詳細(xì)介紹android 字體顏色選擇器(ColorPicker)需要了解更多的朋友可以參考下2012-11-11

