美文网首页
Flutter 之 剪裁(Clip)(四十三)

Flutter 之 剪裁(Clip)(四十三)

作者: maskerII | 来源:发表于2022-05-01 20:30 被阅读0次

    Flutter中提供了一些剪裁函数,用于对组件进行剪裁

    剪裁Widget 默认行为
    ClipOval 子组件为正方形时剪裁成内贴圆形;为矩形时,剪裁成内贴椭圆
    ClipRRect 将子组件剪裁为圆角矩形
    ClipRect 默认剪裁掉子组件布局空间之外的绘制内容(溢出部分剪裁)
    ClipPath 按照自定义的路径剪裁

    示例

    
    class MSClipDemo extends StatelessWidget {
      const MSClipDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        Widget avatar = Image.asset("assets/images/3.jpeg",
            width: 60, height: 60, fit: BoxFit.cover);
        return Scaffold(
          appBar: AppBar(title: Text("ClipDemo")),
          body: Column(
            // mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              avatar, // 不裁剪
              ClipOval(child: avatar), // 裁剪成圆形
              ClipRRect(
                child: avatar,
                borderRadius: BorderRadius.circular(5.0),
              ), // 裁剪成圆角矩形
    
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Align(
                    child: avatar,
                    alignment: Alignment.topLeft,
                    widthFactor: 0.5, //宽度设为原来宽度一半,另一半会溢出
                  ),
                  Text("你好世界", style: TextStyle(color: Colors.red)),
                ],
              ),
    
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ClipRect(
                    // 将溢出部分剪裁
                    child: Align(
                      child: avatar,
                      alignment: Alignment.topLeft,
                      widthFactor: 0.5, //宽度设为原来宽度一半
                    ),
                  ),
                  Text("你好世界", style: TextStyle(color: Colors.red)),
                ],
              ),
            ],
          ),
        );
      }
    }
    
    
    image.png

    最后的两个Row,它们通过Align设置widthFactor为0.5后,图片的实际宽度等于60×0.5,即原宽度一半,但此时图片溢出部分依然会显示,所以第一个“你好世界”会和图片的另一部分重合,为了剪裁掉溢出部分,我们在第二个Row中通过ClipRect将溢出部分剪裁掉了。

    2. CustomClipper

    如果我们想剪裁子组件的特定区域,比如,在上面示例的图片中,如果我们只想截取图片中部40×30像素的范围应该怎么做?这时我们可以使用CustomClipper来自定义剪裁区域,实现代码如下:

      @override
      Rect getClip(Size size) {
        return Rect.fromLTWH(10, 15, 40, 30);
      }
    
      @override
      bool shouldReclip(covariant CustomClipper oldClipper) {
        return false;
      }
    }
    
    • getClip()是用于获取剪裁区域的接口,由于图片大小是60×60,我们返回剪裁区域为Rect.fromLTWH(10.0, 15.0, 40.0, 30.0),即图片中部40×30像素的范围。
    • shouldReclip() 接口决定是否重新剪裁。如果在应用中,剪裁区域始终不会发生变化时应该返回false,这样就不会触发重新剪裁,避免不必要的性能开销。如果剪裁区域会发生变化(比如在对剪裁区域执行一个动画),那么变化后应该返回true来重新执行剪裁。

    示例

    
    class MSCustomClipDemo extends StatelessWidget {
      const MSCustomClipDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        Widget avatar = Image.asset("assets/images/6.jpeg",
            width: 60, height: 60, fit: BoxFit.cover);
        return Scaffold(
          appBar: AppBar(title: Text("CustomClip")),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                avatar,
                SizedBox(height: 10),
                DecoratedBox(
                  decoration: BoxDecoration(color: Colors.red),
                  child: ClipRect(
                    clipper: MSClipper(),
                    child: avatar,
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    
    截屏2022-05-08 下午8.41.16.png

    可以看到我们的剪裁成功了,但是图片所占用的空间大小仍然是60×60(红色区域),这是因为组件大小是是在layout阶段确定的,而剪裁是在之后的绘制阶段进行的,所以不会影响组件的大小,这和Transform原理是相似的。

    ClipPath 可以按照自定义的路径实现剪裁,它需要自定义一个CustomClipper<Path> 类型的 Clipper,定义方式和 MyClipper 类似,只不过 getClip 需要返回一个 Path,不再赘述。

    https://book.flutterchina.club/chapter5/clip.html

    相关文章

      网友评论

          本文标题:Flutter 之 剪裁(Clip)(四十三)

          本文链接:https://www.haomeiwen.com/subject/xsbpyrtx.html