Flutter 133: 图解自定义 ACEWaterButton 水波纹按钮

简介: 0 基础学习 Flutter,第一百三十三步,自定义简单 ACEWaterButton 水波纹按钮!

    小菜想自定义一个水波纹按钮,即默认向外扩散的水波样式;实现方式有很多种,小菜尝试最基本的 AnimationController 逐层绘制来处理,小菜简单记录一下尝试过程;

ACEWaterButton

    小菜画了一个简单的图如下,预期的水波纹按钮包括两层,以中心圆(蓝色)为基础逐步向外围扩散至(绿色),并循环重复;

1. 内置圆

    小菜以此分为两步,第一步先绘制内置圆和内置图标,小菜提供了 innerSizeinnerIcon 属性以方便内置圆的样式自定义;通过 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 水波纹按钮的简单效果已满足,但还不够完善,对于重绘的机制还需要优化;如有错误,请多多指导!

来源: 阿策小和尚
目录
相关文章
|
7月前
|
缓存 Java 开发工具
Flutter的文本、图片和按钮使用
Flutter的文本、图片和按钮使用
68 0
|
4天前
|
前端开发 搜索推荐 开发者
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
【4月更文挑战第30天】本文介绍了如何在Flutter中自定义主题和实现暗黑模式。通过`ThemeData`类定义应用的外观,包括颜色、字体和样式。示例展示了如何设置主色、强调色及文本、按钮主题。暗黑模式可通过`darkTheme`属性启用,结合`ThemeData.dark()`方法定制。利用`MediaQuery`监听系统亮度变化,动态调整暗黑模式状态。Flutter的这些特性有助于开发者创建独特且用户友好的界面。
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
|
4天前
|
缓存 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
【4月更文挑战第30天】Flutter允许开发者通过`CustomPaint`和`CustomPainter`进行自定义绘制,以实现丰富视觉效果。`CustomPaint` widget将`CustomPainter`应用到画布,而`CustomPainter`需实现`paint`和`shouldRepaint`方法。`paint`用于绘制图形,如示例中创建的`MyCirclePainter`绘制蓝色圆圈。Canvas API提供绘制形状、路径、文本和图片等功能。注意性能优化,避免不必要的重绘和利用缓存提升效率。自定义绘制让Flutter UI更具灵活性和个性化,但也需要图形学知识和性能意识。
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
|
4天前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
4天前
|
前端开发 开发者 UED
Flutter的自定义Painter:深入探索自定义绘制Widget的技术实现
【4月更文挑战第26天】Flutter的自定义Painter允许开发者根据需求绘制独特UI,通过继承`CustomPaint`类和重写`paint`方法实现。在`paint`中使用`Canvas`绘制图形、路径等。创建自定义Painter类后,将其作为`CustomPaint` Widget的`painter`属性使用。此技术可实现自定义形状、渐变、动画等复杂效果,提升应用视觉体验。随着Flutter的进化,自定义Painter将提供更丰富的功能。
|
4天前
|
运维 监控 定位技术
应用研发平台EMAS常见问题之flutter插件不支持自定义图标如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
81 0
|
4天前
|
前端开发
Flutter笔记:光影动画按钮、滚动图标卡片组等
Flutter笔记:光影动画按钮、滚动图标卡片组等
42 0
|
4天前
|
iOS开发
Flutter 组件(三)按钮类组件
Flutter 组件(三)按钮类组件
169 0
|
4天前
Flutter 自定义ICON库
Flutter 自定义ICON库 Flutter提供了一些内置的ICON库,但在实际开发中,可能需要一些自定义的ICON图标。Flutter允许我们使用自定义图标,本文将介绍如何创建和使用自定义ICON库。
|
4天前
|
UED
Flutter之自定义路由切换动画
Flutter之自定义路由切换动画 在Flutter中,我们可以通过Navigator来实现路由管理,包括路由的跳转和返回等。默认情况下,Flutter提供了一些简单的路由切换动画,但是有时候我们需要自定义一些特殊的动画效果来提高用户体验。本文将介绍如何在Flutter中实现自定义的路由切换动画。