Code前端首页关于Code前端联系我们

Flutter开发:使用ClipPath实现任意形状Widget

terry 2年前 (2023-09-22) 阅读数 73 #移动小程序

关于ClipPath

我们都应该使用过ClipXXX相关组件来实现一些circular❝circular值导向来实现一些奇怪的Widget ,如五角星形/弧形,您可以直接使用ClipPath

如果您想了解更多关于ClipPath的信息,请直接前往官网下载文档。简介如下:

一个使用路径剪辑子组件的小部件。

每次要绘制该小部件时都会调用委托回调。回调返回一个路径,小部件会阻止子进程在路径之外进行绘画。

修剪路径很昂贵。

使用路径来剪辑孩子的小部件。

每次绘制小部件时,都会在委托上调用回调。回调函数返回一个路径,并且小部件会阻止子进程在路径之外进行绘制。

裁剪路径很昂贵。

一般按照路径来切割子widget,但是切割路径的成本非常高

?我们来看看怎么用吧

关于怎么用,我们先看一下构造函数:

const ClipPath({
  Key key,
  this.clipper, // final CustomClipper<Path> clipper;
  this.clipBehavior = Clip.antiAlias,
  Widget child,
}) : assert(clipBehavior != null),
super(key: key, child: child);
复制代码

首先可以看到,其实需要两个参数,一个是剪刀,另一个是child

child 是由 clipper 切割的组件。你自己写就行了,剩下的就是剪辑

看一下clipper的源码:

/// CustomClipper
abstract class CustomClipper<T> {
  /// Creates a custom clipper.
  ///
  /// The clipper will update its clip whenever [reclip] notifies its listeners.
  const CustomClipper({ Listenable reclip }) : _reclip = reclip;

  final Listenable _reclip;

  /// 返回 clip 的说明 -> T
  T getClip(Size size);

  /// 是否重新 clip
  bool shouldReclip(covariant CustomClipper<T> oldClipper);

}
复制代码

这里去掉了一些方法,只保留了我们需要重写的方法。最重要的是 T getClip(Size size)

传入ClipPath的泛型类型为。其实我们很熟悉的 ClipRect / ClipRRect / ClipOvalC 对应C空剪唇器 / CustomClipper / 就这样。

所以这里我们只需要定义自己的Path就可以实现任意形状的widget。

?开始实现自定义小部件

让我们实现以下形状(顶部是原始图像,底部是裁剪后的):

Flutter开发:利用 ClipPath 实现任意形状 Widget总而言之,您只需要实现一个 CustomClipper 然后提交 将参数 clipper 输入到 ClipPath

代码如下:

class MyClipper extends CustomClipper<Path> {

  @override
  Path getClip(Size size) {
    Path path = Path();
    // 从 60,0 开始
    path.moveTo(60, 0);
    // 二阶贝塞尔曲线画弧
    path.quadraticBezierTo(0, 0, 0, 60);
    // 连接到底部
    path.lineTo(0, size.height / 1.2);
    // 三阶贝塞尔曲线画弧
    path.cubicTo(size.width / 4, size.height, size.width / 4 * 3, size.height / 1.5, size.width, size.height / 1.2);
    // 再连接回去
    path.lineTo(size.width, 60);
    // 再用二阶贝塞尔曲线画弧
    path.quadraticBezierTo(size.width - 60, 60, size.width - 60, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
复制代码

逻辑我不想讲,全在注释里。

?总结

因为ClipPath比较贵,所以如果只想切圆角,建议使用内置的ClipRRect或者类似的。他们的性能更好(官方文档说)。

ClipPath还有一个静态方法ClipPath.shape()。我不会详细介绍这一点。有兴趣的话可以查看源码。

作者:Flutter笔记
链接:https://juejin.im/post/5ecfc037f265da76b4048769
来源:掘金
版权归作者所有。商业转载请联系作者获取授权。非商业转载请注明来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门