概述

Flutter 提供了一些工具类的 Widget,可以帮助我们进行一些特殊的操作,例如对 Widget 进行剪切,设置透明度,旋转等等,这节将一下剪切。

和剪切相关的 Widget 有:

  • ClipRect:矩形裁剪

  • ClipOval: 圆形裁剪

  • ClipRRect: 圆角矩形裁剪
  • ClipPath: 路径裁剪

矩形剪切——ClipRect

将 child 剪裁为给定的矩形大小,先看构造方法:

ClipRect({ Key key, 
          this.clipper, 
          this.clipBehavior = Clip.hardEdge, 
          Widget child })

ClipRect 参数

  • clipper,CustomClipper 对象,如果为空,则裁剪区域为 child 指定的大小
  • clipBehavior,裁剪的方式, 不能为 null 或者 Clip.none;共有以下几个选项:
    • none:不裁剪
    • hardEdge:裁剪但不应用抗锯齿,裁剪速度比 none 模式慢一点,但比其他方式快。
    • antiAlias:裁剪而且抗锯齿,以实现更平滑的外观。裁剪速度比 antiAliasWithSaveLayer 快,比hardEdge 慢。
    • antiAliasWithSaveLayer:带有抗锯齿的剪辑,并在剪辑之后立即保存 saveLayer
  • child,子布局

ClipRect 通常和以下 Widget 搭配使用:

示例:

      body: Column(
        children: <Widget>[
            //正常图片
          Image.asset("assets/images/girl.png"),
            //剪切
          ClipRect(
            child: Center(
              heightFactor: 0.3,
              widthFactor: 0.5,
              child: Image.asset(
                "assets/images/girl.png",
              ),
            ),
          )
        ],
      ),

显示效果如图:

圆形剪切——ClipOval

将 Widget 剪切为圆形,构造方法:

const ClipOval({ Key key, 
                this.clipper, 
                this.clipBehavior = Clip.antiAlias, 
                Widget child })

ClipOval 参数

参数含义同 ClipRect,不多做解释。

  • clipper
  • clipBehavior
  • child

示例

      body: Column(
        children: <Widget>[
          Image.asset("assets/images/girl.png"),
          ClipOval(
            child: Image.asset(
              "assets/images/girl.png",
            ),
          )
        ],
      ),

效果如下:

圆角矩形剪切——ClipRRect

构造函数:

  const ClipRRect({
    Key key,
    this.borderRadius,
    this.clipper,
    this.clipBehavior = Clip.antiAlias,
    Widget child,
  })

ClipRRect 参数

比上两个剪切方式多了一个 borderRadius,用于设置圆角的大小,其余参数和前面两个一样。

示例

      body: Column(
        children: <Widget>[
          Image.asset("assets/images/girl.png"),
          ClipRRect(
            borderRadius: BorderRadius.horizontal(left: Radius.circular(50),right: Radius.circular(10)),
            child: Image.asset(
              "assets/images/girl.png",
            ),
          )
        ],
      ),

效果如下:

路径剪切——ClipPath

路径剪切有两种方式,一种是使用系统自带的路径,一种是自定义路径

自带路径

使用系统自带的路径主要是通过 ClipPathshap 方法:

  static Widget shape({
    Key key,
    @required ShapeBorder shape,
    Clip clipBehavior = Clip.antiAlias,
    Widget child,
  })

主要设置 shape 参数,系统预置了一些参数供我们选择:

  • RoundedRectangleBorder,圆角矩形

          body: Column(
            children: <Widget>[
              Image.asset("assets/images/girl.png"),
              ClipPath.shape(
                shape: RoundedRectangleBorder(
                    borderRadius:BorderRadius.circular(50)
                ),
                child: Image.asset(
                  "assets/images/girl.png",
                ),
              )
            ],
          ),
    

    效果如下:

  • ContinuousRectangleBorder,直线和圆角平滑连续的过渡,和 RoundedRectangleBorder 相比,圆角效果会小一些。

          body: Column(
            children: <Widget>[
              Image.asset("assets/images/girl.png"),
              ClipPath.shape(
                shape: ContinuousRectangleBorder(
                    borderRadius: BorderRadius.circular(150)),
                child: Image.asset(
                  "assets/images/girl.png",
                ),
              )
            ],
          ),
    

    效果如下:

  • StadiumBorder,两端(上下或者左右)圆形的切割,对于正方形的 Widget 来说,切割完成之后的效果是一个圆形,只有长宽不相等的时候才会有效果:

          body: Column(
            children: <Widget>[
              Image.asset("assets/images/girl.png"),
              ClipRect(
                child: Align(
                  heightFactor: 0.5,
                  child: ClipPath.shape(
                    shape:
                    StadiumBorder(),
                    child: Image.asset(
                      "assets/images/girl.png",
                    ),
                  ),
                ),
              ),
            ],
          ),
    

    效果如下:

  • BeveledRectangleBorder,斜角矩形

          body: Column(
            children: <Widget>[
              Image.asset("assets/images/girl.png"),
              ClipPath.shape(
                shape: BeveledRectangleBorder(
                    borderRadius:BorderRadius.all(Radius.circular(30))
                ),
                child: Image.asset("assets/images/girl.png"),
              ),
            ],
          ),
    

    效果如下:

  • CircleBorder,圆形剪切

          body: Column(
            children: <Widget>[
              Image.asset("assets/images/girl.png"),
              ClipPath.shape(
                shape: CircleBorder(
                ),
                child: Image.asset("assets/images/girl.png"),
              ),
            ],
          ),
    

    效果如下:

自定义路径

除了上述的系统预设的路径切割,我们还可以自定义路径进行切割,路径的创建方式和 Android 一样:

class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with SingleTickerProviderStateMixin {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scaffold Test'),
      ),
      body: Column(
        children: <Widget>[
          Image.asset("assets/images/girl.png"),
          ClipPath(
            clipper: MyCustomClipPath(),
            child: Image.asset("assets/images/girl.png"),
          ),
        ],
      ),
    );
  }
}

class MyCustomClipPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(size.width, 0);
    path.lineTo(size.width/2, size.height/2);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    // TODO: implement shouldReclip
    return true;
  }
}

效果如下:

results matching ""

    No results matching ""