Advertisement

flutter 页面加载动画_十、Flutter加载动画

阅读量:

目录

一、效果展示

二、RoundPainter

三、RoundProgress

四、旋转起来

五、停止旋转

一、效果展示

Flutter加载动画.jpg

二、RoundPainter

同上篇文章《九、Flutter水波动画》画水波原理是一样的,都是通过画笔呈现不规则图形。this.offsetList是存储加载的动画里面的实心圆的坐标,通过drawCircle方法把坐标画到画布上。

@override

void paint(Canvas canvas, Size size) {

for (int i = 0; i < this.offsetList.length; i++) {

var paint = new Paint()

..color = this.color

..style = PaintingStyle.fill;

canvas.drawCircle(this.offsetList[i], this.radiusList[i], paint);

}

}

三、RoundProgress

RoundProgress继承StatefulWidget通过 Timer刷新页面,来达到动画的效果。this.w * i / this.numOfMoveView是计算每个实心圆的宽度的,i越小实心圆的宽度越小,实心圆就越小。(pi * 2.0 / this.numOfMoveView) * i计算出弧度,通过弧度计算出每个实心圆的坐标,保存在this.offsetList里。每个实心圆初始化的弧度都保存在了 this.radianList里,循环第二次,第三次......累计弧度,每个实心圆的坐标逐一按弧度偏移,从而所有的实心圆绕着一个点旋转。

this.timer = Timer.periodic(new Duration(milliseconds: 80), (timer) {

setState(() {

double r = this.width;

if (r > this.height) {

r = this.height;

}

r = r / 2.0;

r = r * this.moveSize;

double w = r * sin(2 * pi / this.numOfMoveView) / 2.0;

r -= (w / 2.0);

w = w * this.moveViewSize;

this.r = r;

this.w = w;

List oList = [];

List rList = [];

List radianList = [];

for (int i = 1; i < this.numOfMoveView + 1; i++) {

w = this.w * i / this.numOfMoveView;

double radian = (pi * 2.0 / this.numOfMoveView) * I;

Offset offset = Offset(this.width / 2.0 + this.r * cos(radian),

this.r * sin(radian) + this.height / 2.0);

if (this.radianList.length > 0) {

radian = this.radianList[i - 1] + pi * 2.0 / (2.0 *this.numOfMoveView);

offset = Offset(this.width / 2.0 + this.r * cos(radian),

this.height / 2.0 + this.r * sin(radian));

}

oList.add(offset);

rList.add(w / 2.0);

radianList.add(radian);

}

this.offsetList = oList;

this.radiusList = rList;

this.radianList = radianList;

});

});

四、旋转起来

RoundProgress最重的一个参数loading,当loading = true加载动画会在stack里面呈现出来,当loading = false加载动画不会出现在stack里面。

this.loading = true;

RoundProgress(

key: this.key,

loading: this.loading,

width: 160,

height: 160,

child: Center(

child: Center(

child: Text("正在加载数据..."),

)),

),

五、停止旋转

由于RoundProgress继承了StatefulWidget,从外部就没有办法更新RoundProgress数据了,可以通过组件间通信。这里使用的是Global Key通信,可以访问State对象的公共属性和方法,从而让加载动画停止旋转,刷新组件。另外还有一种通信方法是ValueNotifier通信,ValueNotifier是一个包含单个值的变更通知器,当它的值改变的时候,会通知它的监听。

final key = GlobalKey();

setState(() {

this.loading = false;

this.key.currentState.updateLoad(this.loading);

this.updateChild();

});

总结:这个加载动画算是初步完成了,基本使用还是可以的,封装的不够灵活,可自定义程度比较低。下一篇文章将进一步对加载动画优化,并上传到pub.dev方便大家使用。谢谢收看,点个赞吧!

全部评论 (0)

还没有任何评论哟~