【剪裁 widget】Flutter ClipOval 与 Flutter ClipRRect

简介: 【剪裁 widget】Flutter ClipOval 与 Flutter ClipRRect

image.png

本文是 【剪裁 widget】系列的第三篇,也是最后一篇,今天介绍一下ClipOval 和 ClipRRect。

ClipOval 介绍

Flutter ClipOval 用 椭圆形去剪裁 child,path 以外的部分不显示,还能高效的实现动画。

剪裁是在绘制阶段,具体实现是在 paint 方法中调用 PaintingContext 类的 pushClipPath 方法进行剪裁。

void paint(PaintingContext context, Offset offset) { 
...
 layer = context.pushClipPath(
    needsCompositing,
    offset,
    Offset.zero & size,
    _clip!,
    super.paint,
    clipBehavior: clipBehavior,
    oldLayer: layer as ClipPathLayer?,
  );
 ...
}
复制代码

和 ClipPath 一样,调用 PaintingContext 的 pushClipPath。所以从本质上来看, ClipOval 和 ClipPath是一样的,相当于是给 ClipPath 起了一个别名。ClipOval 的唯一价值就是可以增加可读性,而且它会把 Rect 自动转为 Oval path,用起来更方便些。

Path _getClipPath(Rect rect) {
    if (rect != _cachedRect) {
      _cachedRect = rect;
      _cachedPath = Path()..addOval(_cachedRect!);
    }
    return _cachedPath;
}
复制代码

ClipPath 的参数 clipper 的类型是 CustomClipper,ClipOval 的参数 clipper 的类型是 CustomClipper,所以ClipOval更容易使用。上面代码_getClipPath 的参数 rect 就是 clipper.getClip 返回的 Rect。

ClipOval 的默认效果是把原来的矩形 widget 剪裁成 内切椭圆,如果原来的矩形是正方形,那么剪裁的结果就是一个圆。如果要得到不同的剪裁结果 ,就需要自定义剪裁。

自定义 Oval 剪裁

我们可以指定 clipper 参数进行自定义裁剪。

举个例子,我们想裁剪出花朵的部分。图片大小为 100 x 100。

image.png

class MyClipper extends CustomClipper<Rect> {
  @override
  Rect getClip(Size size) {
    return Rect.fromLTWH(20, 10, 65, 65);
  }
  @override
  bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
    return false;
  }
}
复制代码
Center(
    child: ClipOval(
      clipper: MyClipper(),
      child: Image.network(
        'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9eb382cf5d7341938dfbf6fa2442242e~tplv-k3u1fbpfcp-watermark.image?',
       width: 100,
       height: 100,
     ),
   ),
);
复制代码

ClipPath 的 MyClipper 几乎完全一样,就是把类型换成了 Rect。

ClipRRect 介绍

Flutter ClipRRect 用圆角矩形去剪裁 child,path 以外的部分不显示,还能高效的实现动画。

剪裁是在绘制阶段,具体实现是在 paint 方法中调用 PaintingContext 类的 pushClipRRect 方法进行剪裁。只是比 ClipRect 多了一个参数 borderRadius,clipper 的类型不同。

默认情况下 ClipRRect 没有效果的,指定 borderRadius,可以把四角剪裁成圆角,但如果要在不同的位置进行剪裁,需要自定义。

下面通过一个示例演示一下 ClipRRect 自定义剪裁的用法

自定义 RRect 剪裁

image.png

class MyClipper extends CustomClipper<RRect> {
  @override
  RRect getClip(Size size) {
    return RRect.fromRectAndRadius(Rect.fromLTWH(20, 10, 65, 65),Radius.circular(21));
  }
  @override
  bool shouldReclip(covariant CustomClipper<RRect> oldClipper) {
    return false;
  }
}
复制代码
Center(
   child: ClipRRect(
     borderRadius:BorderRadius.all(Radius.circular(21)) ,
     clipper: MyClipper(),
     child: Image.network(
       'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/85a4c49c34434ef3a21dc9458c355866~tplv-k3u1fbpfcp-watermark.image?',
         width: 100,
         height: 100,
       ),
     ),
   )
复制代码

应用场景

Flutter ClipOval 与 Flutter ClipRRect 的应用场景和 ClipRect 是一样的,不再赘述,也是剪裁 widget 和制作动画。在 【剪裁 widget】Flutter ClipRect 一文中对如何写动画有举例。

剪裁 widget 结束语

如果你是按顺序先看第一篇 ClipRect,再看第二篇 ClipPath,然后再看这篇,你会觉得非常轻松。知识是有联系的,找到破入点,然后一网打尽。

目录
相关文章
|
15天前
深入理解Flutter鸿蒙next版本 中的Widget继承:使用extends获取数据与父类约束
本文详细介绍了Flutter中如何通过继承其他Widget来创建自定义组件。首先解释了Widget继承的基本概念,包括StatelessWidget和StatefulWidget的区别。接着通过具体示例展示了如何继承StatelessWidget和StatefulWidget,并在子类中访问父类的build方法和状态。最后,结合多个自定义Widget展示了如何在实际应用中灵活使用继承和组合来构建复杂的UI。
66 8
|
13天前
|
容器
flutter&鸿蒙next 使用 InheritedWidget 实现跨 Widget 传递状态
在 Flutter 中,状态管理至关重要。本文详细介绍了如何使用 InheritedWidget 实现跨 Widget 的状态传递。InheritedWidget 允许数据在 Widget 树中向下传递,适用于多层嵌套的场景。通过一个简单的计数器示例,展示了如何创建和使用 InheritedWidget,包括其基础概念、工作原理及代码实现。虽然 InheritedWidget 较底层,但它是许多高级状态管理解决方案的基础。
88 2
|
1月前
|
容器
flutter:第一个flutter&Widget的使用 (二)
本文介绍了Flutter框架下的基本组件及其用法,包括简单的 Stateless Widget 如文本和按钮,以及更复杂的 StatefulWidget 示例。详细解释了如何使用 `context` 获取祖先小部件的信息,并展示了 `MaterialApp` 的属性及用途。此外,还探讨了 `StatefulWidget` 与 `StatelessWidget` 的区别,以及 `AppBar` 的常见属性配置方法。适合Flutter初学者参考学习。
|
13天前
|
Dart JavaScript 前端开发
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
Flutter 是 Google 开发的开源 UI 框架,用于快速构建高性能的移动、Web 和桌面应用。Flutter 通过 Widget 构建 UI,每个 UI 元素都是 Widget,包括文本、按钮、图片等。Widget 不仅描述外观,还描述行为,是不可变的。常见的 Widget 包括结构型(Container、Column、Row)、呈现型(Text、Image)、交互型(ElevatedButton)和状态管理型(StatefulWidget)。Flutter 与鸿蒙 Next 在组件化架构、开发语言、布局系统、性能和跨平台支持方面各有优势
64 0
|
4月前
Flutter-底部弹出框(Widget层级)
文章描述了如何在Flutter中使用DraggableScrollableSheet创建一个底部弹出框,同时保持其可手势滑动关闭。作者遇到问题并提出对原控件进行扩展,以支持头部和列表布局的滑动关闭功能。
180 0
|
5月前
Flutter StreamBuilder 实现局部刷新 Widget
Flutter StreamBuilder 实现局部刷新 Widget
43 0
|
6月前
|
Android开发
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
|
6月前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
76 0
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
6月前
|
JavaScript 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
【4月更文挑战第30天】本文探讨了Flutter的Widget和状态管理。Widget是Flutter构建UI的基础,分为有状态和无状态两种。状态管理确保UI随应用状态变化更新,影响应用性能和可维护性。文章介绍了`setState`、`Provider`、`Riverpod`、`Bloc`和`Redux`等状态管理方法,并通过计数器应用展示了其实现。选择合适的状态管理策略对高效开发至关重要。
85 0
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
|
6月前
|
编解码 算法 开发者
Flutter的布局系统:深入探索布局Widget与布局原则
【4月更文挑战第26天】Flutter布局系统详解,涵盖布局Widget(Row/Column、Stack、GridView/ListView、CustomSingleChildLayout)和布局原则(弹性布局、约束优先、流式布局、简洁明了)。文章旨在帮助开发者理解并运用Flutter的布局系统,创建适应性强、用户体验佳的界面。通过选择合适的布局Widget和遵循原则,可实现复杂且高效的UI设计。