Flutter 133: 图解自定义 ACEWaterButton 水波纹按钮
小菜想自定义一个水波纹按钮,即默认向外扩散的水波样式;实现方式有很多种,小菜尝试最基本的 AnimationController 逐层绘制来处理,小菜简单记录一下尝试过程;
ACEWaterButton
小菜画了一个简单的图如下,预期的水波纹按钮包括两层,以中心圆(蓝色)为基础逐步向外围扩散至(绿色),并循环重复;
(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>)
1. 内置圆
小菜以此分为两步,第一步先绘制内置圆和内置图标,小菜提供了 innerSize 和 innerIcon 属性以方便内置圆的样式自定义;通过 ClipOval 裁切一个完整的内置圆;
其中需要注意的是,内置圆应置于外围圆的中心,因此小菜添加一个 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. 水波纹
小菜预想实现水波纹效果则必然离不开 Animation 动画,使用动画方式也有多种,可以继承 AnimatedWidget 也可以使用 AnimationController 自定义动画样式;
小菜预期水波纹不仅范围逐渐变大,并且在扩散过程中透明度逐渐降低,至外围最大范围为止消失;小菜采用最基本的 CustomPainter 自定义 Canvas.drawCircle,根据时间进度来逐层绘制水波纹;
2.1 透明度
小菜使用 Paint 绘制时根据 AnimationController.value 进度逐步设置 color.withOpacity 透明度逐渐变低;
Paint _paint = Paint()..style = PaintingStyle.fill; _paint..color = color.withOpacity(1.0 - progress);
2.2 外围圆
外围圆主要是根据 AnimationController.value 进度逐步进行半径的更新;小菜预期的水波纹范围只有默认的内置圆到外围圆的范围渐变,因此变动范围为 (outSize – innerSize) 0.5 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);
小菜在测试过程中也尝试了其他的扩展范围,若起始位置为中心则无需添加内置圆半径;若想增大或见效水波纹范围可以自由调整 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 内置圆是否可缺省?
小菜在通过 ACEWaterPainter 绘制水波纹过程中,起始位置从内置圆开始,那是否可以省略第一步的内置圆呢?
暂时先不缺省,因为小菜在设置水波纹扩散过程中,同时设置了透明度的渐变,若缺省内置圆会影响 innerIcon 的展示效果;但内置圆绘制位置可以调整,也可以在 ACEWaterPainter 中进行绘制;
3.2 shouldRepaint 是否需要一直重绘?
ACEWaterPainter 中是否需要一直重绘;在使用自定义 Paint 委托类创建新的 CustomPaint 对象时若新实例与旧实例不同,则应返回 true,否则应返回 false;因此在水波纹过程中,小菜默认设置为 true 进行重绘;
ACEWaterButton 案例源码
小菜对 ACEWaterButton 水波纹按钮的简单效果已满足,但还不够完善,对于重绘的机制还需要优化;如有错误,请多多指导!
来源: 阿策小和尚
你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:
相关文章
- Jgit的使用笔记
- 利用Github Action实现Tornadofx/JavaFx打包
- 叹息!GitHub Trending 即将成为历史!
- 微软软了?开源社区讨论炸锅,GitHub CEO 亲自来答
- GitHub Trending 列表频现重复项,前后端都没去重?
- Photoshop Elements 2021版本软件安装教程(mac+windows全版本都有)
- (ps全版本)Photoshop 2020的安装与破解教程(mac+windows全版本都有)
- (ps全版本)Photoshop cc2018的安装与破解教程(mac+windows全版本,包括2023
- 环境搭建:Oracle GoldenGate 大数据迁移到 Redshift/Flat file/Flume/Kafka测试流程
- 每个开发人员都要掌握的:最小 Linux 基础课
- 来撸羊毛了!Windows 环境下 Hexo 博客搭建,并部署到 GitHub Pages
- 超实用!手把手入门 MongoDB:这些坑点请一定远离
- 【GitHub日报】22-10-09 zustand、neovim、webtorrent、express 等4款App今日上新
- 【GitHub日报】22-10-10 brew、minio、vite、seaweedfs、dbeaver 等8款App今日上新
- 【GitHub日报】22-10-11 cobra、grafana、vue、ToolJet、redwood 等13款App今日上新
- Photoshop 2018 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2017 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2020 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2023 资源免费下载(mac+windows全版本都有,包括最新的2023)
- 最新版本Photoshop CC2018软件安装教程(mac+windows全版本都有,包括2023