Flutter 133: 圖解自定義 ACEWaterButton 水波紋按鈕

????小菜想自定義一個水波紋按鈕洞翩,即默認向外擴散的水波樣式焊虏;實現(xiàn)方式有很多種,小菜嘗試最基本的 AnimationController 逐層繪制來處理啥容,小菜簡單記錄一下嘗試過程锈颗;

ACEWaterButton

????小菜畫了一個簡單的圖如下,預期的水波紋按鈕包括兩層干毅,以中心圓(藍色)為基礎逐步向外圍擴散至(綠色)宜猜,并循環(huán)重復;

1. 內(nèi)置圓

????小菜以此分為兩步硝逢,第一步先繪制內(nèi)置圓和內(nèi)置圖標姨拥,小菜提供了 innerSizeinnerIcon 屬性以方便內(nèi)置圓的樣式自定義;通過 ClipOval 裁切一個完整的內(nèi)置圓渠鸽;

????其中需要注意的是叫乌,內(nèi)置圓應置于外圍圓的中心,因此小菜添加一個 outSize 屬性限制外圍圓尺寸徽缚,同時默認設置 innerSize = 48.0憨奸,若未設置 outSize,則以 innerSize * 2 為默認值凿试;

Container(
    width: widget.outSize ?? widget.innerSize * 2,
    height: widget.outSize ?? widget.innerSize * 2,
    child: widget.innerIcon == null
        ? Container() : Center(child: ClipOval(
                child: Container(
                    width: widget.innerSize,
                    height: widget.innerSize,
                    color: widget.color,
                    child: widget.innerIcon))))

2. 水波紋

????小菜預想實現(xiàn)水波紋效果則必然離不開 Animation 動畫排宰,使用動畫方式也有多種,可以繼承 AnimatedWidget 也可以使用 AnimationController 自定義動畫樣式那婉;

????小菜預期水波紋不僅范圍逐漸變大板甘,并且在擴散過程中透明度逐漸降低,至外圍最大范圍為止消失详炬;小菜采用最基本的 CustomPainter 自定義 Canvas.drawCircle盐类,根據(jù)時間進度來逐層繪制水波紋;

2.1 透明度

????小菜使用 Paint 繪制時根據(jù) AnimationController.value 進度逐步設置 color.withOpacity 透明度逐漸變低呛谜;

Paint _paint = Paint()..style = PaintingStyle.fill;
_paint..color = color.withOpacity(1.0 - progress);

2.2 外圍圓

????外圍圓主要是根據(jù) AnimationController.value 進度逐步進行半徑的更新在跳;小菜預期的水波紋范圍只有默認的內(nèi)置圓到外圍圓的范圍漸變,因此變動范圍為 (outSize - innerSize) * 0.5 * progress隐岛,同時起始位置為內(nèi)置圓猫妙,因此初始半徑應再加上內(nèi)置圓半徑;

double _radius = ((outSize ?? innerSize * 2) * 0.5 - innerSize * 0.5) * progress + innerSize * 0.5;
canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.5), _radius, _paint);

????小菜在測試過程中也嘗試了其他的擴展范圍聚凹,若起始位置為中心則無需添加內(nèi)置圓半徑吐咳;若想增大或見效水波紋范圍可以自由調(diào)整 AnimationController.value 進度范圍逻悠;

// 中心點擴展
double _radius = innerSize * 0.5 * progress;
// 增大擴展范圍
double _radius = innerSize * 2 * progress;
class ACEWaterPainter extends CustomPainter {
  final double progress;
  final Color color;
  final double innerSize;
  final double outSize;

  Paint _paint = Paint()..style = PaintingStyle.fill;

  ACEWaterPainter(this.progress, this.color, this.innerSize, this.outSize);

  @override
  void paint(Canvas canvas, Size size) {
    _paint..color = color.withOpacity(1.0 - progress);

    double _radius =
        ((outSize ?? innerSize * 2) * 0.5 - innerSize * 0.5) * progress + innerSize * 0.5;

    canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.5), _radius, _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

3. 小反思

3.1 內(nèi)置圓是否可缺试韭脊?

????小菜在通過 ACEWaterPainter 繪制水波紋過程中,起始位置從內(nèi)置圓開始单旁,那是否可以省略第一步的內(nèi)置圓呢沪羔?

????暫時先不缺省,因為小菜在設置水波紋擴散過程中象浑,同時設置了透明度的漸變蔫饰,若缺省內(nèi)置圓會影響 innerIcon 的展示效果;但內(nèi)置圓繪制位置可以調(diào)整愉豺,也可以在 ACEWaterPainter 中進行繪制篓吁;

3.2 shouldRepaint 是否需要一直重繪?

????ACEWaterPainter 中是否需要一直重繪蚪拦;在使用自定義 Paint 委托類創(chuàng)建新的 CustomPaint 對象時若新實例與舊實例不同杖剪,則應返回 true,否則應返回 false驰贷;因此在水波紋過程中盛嘿,小菜默認設置為 true 進行重繪;


????ACEWaterButton 案例源碼


????小菜對 ACEWaterButton 水波紋按鈕的簡單效果已滿足括袒,但還不夠完善次兆,對于重繪的機制還需要優(yōu)化;如有錯誤锹锰,請多多指導芥炭!

來源: 阿策小和尚

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恃慧,隨后出現(xiàn)的幾起案子园蝠,更是在濱河造成了極大的恐慌,老刑警劉巖糕伐,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰琢,死亡現(xiàn)場離奇詭異,居然都是意外死亡良瞧,警方通過查閱死者的電腦和手機陪汽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來褥蚯,“玉大人挚冤,你說我怎么就攤上這事≡奘” “怎么了训挡?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵澳骤,是天一觀的道長。 經(jīng)常有香客問我澜薄,道長为肮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任肤京,我火速辦了婚禮颊艳,結果婚禮上,老公的妹妹穿的比我還像新娘忘分。我一直安慰自己棋枕,他們只是感情好,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布妒峦。 她就那樣靜靜地躺著重斑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肯骇。 梳的紋絲不亂的頭發(fā)上窥浪,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音累盗,去河邊找鬼寒矿。 笑死,一個胖子當著我的面吹牛若债,可吹牛的內(nèi)容都是我干的符相。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蠢琳,長吁一口氣:“原來是場噩夢啊……” “哼啊终!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起傲须,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蓝牲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后泰讽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體例衍,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年已卸,在試婚紗的時候發(fā)現(xiàn)自己被綠了佛玄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡累澡,死狀恐怖梦抢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愧哟,我是刑警寧澤奥吩,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布哼蛆,位于F島的核電站,受9級特大地震影響霞赫,放射性物質(zhì)發(fā)生泄漏腮介。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一绩脆、第九天 我趴在偏房一處隱蔽的房頂上張望萤厅。 院中可真熱鬧,春花似錦靴迫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疟羹,卻和暖如春主守,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榄融。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工参淫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人愧杯。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓涎才,卻偏偏與公主長得像,于是被迫代替她去往敵國和親力九。 傳聞我的和親對象是個殘疾皇子耍铜,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容