Flutter水波紋邊框

3g54o-00xsw (1).gif

使用AnimationController控制兩種動畫效果局嘁,分別是縮放動畫ScaleTransition和淡出動畫FadeTransition,多圈波紋需要多個AnimationController,把所有controller放在數(shù)組里退出時一并銷毀,
波紋widget以Stack結(jié)構(gòu)層層疊加

完整代碼:

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class WaveBorder extends StatefulWidget {
  final Widget child; // 子控件
  final int count; // 波紋圈數(shù)
  final double width; // 波紋直徑
  final double maxWidth; // 波紋擴(kuò)散后最大直徑
  final Color borderColor; // 波紋邊框顏色
  final double borderWidth; // 波紋粗細(xì)
  final Duration duration; // 波紋擴(kuò)散動畫時長(毫秒)

  WaveBorder({
    Key key,
    this.child,
    this.count = 1,
    this.width,
    this.maxWidth,
    this.borderColor = Colors.white,
    this.borderWidth = 1,
    this.duration = const Duration(milliseconds: 5000),
  }) : super(key: key);

  @override
  _WaveBorderState createState() => _WaveBorderState();
}

class _WaveBorderState extends State<WaveBorder> with TickerProviderStateMixin {
  List<AnimationController> _controllerList = []; // 動畫控制器數(shù)組
  List<Widget> children = []; // 子組件數(shù)組(所有波紋 + child)

  @override
  void initState() {
    super.initState();

    // 配置動畫和子控件
    configAnimation();
  }

  configAnimation() {
    for (int i = 0; i < widget.count; i++) {
      // 動畫控制器
      var controller = AnimationController(
        vsync: this,
        duration: widget.duration,
      );
      // 控制器放數(shù)組里方便銷毀
      _controllerList.add(controller);

      // 波紋放大比例
      double endScale = widget.maxWidth / widget.width;

      // 放大動畫
      var scaleAnimation = Tween(
        begin: 1.0,
        end: endScale,
      ).animate(controller);

      // 透明動畫
      var opacityAnimation = Tween(
        begin: 1.0,
        end: 0.0,
      ).animate(controller);

      // 添加波紋組件
      children.add(_borderWidget(scaleAnimation, opacityAnimation));

      // 每道波紋動畫間隔
      int interval = widget.duration.inMilliseconds ~/ widget.count;

      Future.delayed(Duration(milliseconds: i * interval), () {
        // 執(zhí)行動畫
        if (mounted) {
          controller.repeat();
        }
      });
    }

    // 添加子控件child
    if (widget.child != null) {
      children.add(widget.child);
    }
  }

  @override
  void dispose() {
    // 銷毀動畫控制器
    _controllerList.forEach((controller) {
      controller.dispose();
    });
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: children,
    );
  }

  Widget _borderWidget(Animation scaleAnimation, Animation opacityAnimation) {
    return ScaleTransition(
      alignment: Alignment.center,
      scale: scaleAnimation,
      child: FadeTransition(
        opacity: opacityAnimation,
        child: Container(
          width: widget.width,
          height: widget.width,
          decoration: BoxDecoration(
            color: Colors.transparent,
            borderRadius: BorderRadius.circular(widget.width / 2),
            border: Border.all(color: widget.borderColor, width: widget.borderWidth),
          ),
        ),
      ),
    );
  }
}

使用:

WaveBorder(
    width: 200.w,
    maxWidth: 300.w,
    count: 2,
    borderColor: Colors.white,
    borderWidth: 1,
    duration: Duration(milliseconds: 4000),
    child: MusicPlayBtn(playing: isPlaying.value),
);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市试吁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌楼咳,老刑警劉巖熄捍,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爬橡,居然都是意外死亡治唤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門糙申,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宾添,“玉大人,你說我怎么就攤上這事柜裸÷粕拢” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵疙挺,是天一觀的道長扛邑。 經(jīng)常有香客問我,道長铐然,這世上最難降的妖魔是什么蔬崩? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮搀暑,結(jié)果婚禮上沥阳,老公的妹妹穿的比我還像新娘。我一直安慰自己自点,他們只是感情好桐罕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桂敛,像睡著了一般功炮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上术唬,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天魁索,我揣著相機(jī)與錄音侨核,去河邊找鬼撼唾。 笑死齿兔,一個胖子當(dāng)著我的面吹牛撬码,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播殴瘦,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼健盒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了巴碗?” 一聲冷哼從身側(cè)響起朴爬,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎橡淆,沒想到半個月后召噩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逸爵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年具滴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片师倔。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡构韵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出趋艘,到底是詐尸還是另有隱情疲恢,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布瓷胧,位于F島的核電站显拳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏搓萧。R本人自食惡果不足惜杂数,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘸洛。 院中可真熱鬧揍移,春花似錦、人聲如沸货矮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囚玫。三九已至喧锦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抓督,已是汗流浹背燃少。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铃在,地道東北人阵具。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓碍遍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阳液。 傳聞我的和親對象是個殘疾皇子怕敬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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