Flutter 116: 图解 PhysicalModel & PhysicalShape 裁切小组件

简介: 0 基础学习 Flutter,第一百一十六步:简单了解 PhysicalModel 裁切小组件!

    小菜在学习过程中发现仅通过设置 decoration 是无法改变 Container 内部 Widget 样式的,一般我们会通过 ClipX 方式进行裁剪;而一旦涉及到 Widget 的裁剪,对于基础样式,通常会采用 ClipOval / ClipRRect / ClipPath 等方式,对于稍加复杂的样式,一般通过自定义 CustomClipper 也可以满足;

    而小菜今天尝试另一种类似的 PhysicalModel 方式;PhysicalX 方式可以设置 Widget 阴影效果,而 ClipX 方式不行;

PhysicalModel

源码分析

const PhysicalModel({
    Key key,
    this.shape = BoxShape.rectangle,    // 裁剪样式
    this.clipBehavior = Clip.none,      // 裁剪方式
    this.borderRadius,                  // 圆角弧度
    this.elevation = 0.0,               // 阴影高度
    @required this.color,               // 背景色
    this.shadowColor = const Color(0xFF000000),     // 阴影颜色
    Widget child,
})

    分析源码可得,PhysicalModel 是一个样式相对单一的裁切 Widget,其中 color 背景色是必不可少的,而真正影响阴影颜色的为 shadowColor

案例尝试

1. shape & borderRadius

    shape 为裁剪样式,包括 BoxShape.rectangleBoxShape.circle 两种,分别对应 ClipRRectClipOval,而 borderRadius 只有在 rectangle 圆角情况下生效;其中 clipBehavior 与其他涉及到裁切方式一致;

// ClipX
return ClipRRect(
    borderRadius: BorderRadius.all(Radius.circular(20.0)),
    child: Container(width: 80.0, height: 80.0, child: Image.asset('images/icon_hzw01.jpg')));
return Container(
    width: 80.0, height: 80.0,
    child: ClipOval(child: Image.asset('images/icon_hzw01.jpg', fit: BoxFit.fill)));

// PhysicalModel
return PhysicalModel(
    color: Colors.transparent,
    shape: isCircle ? BoxShape.circle : BoxShape.rectangle,
    clipBehavior: Clip.antiAlias,
    borderRadius: BorderRadius.all(Radius.circular(20.0)),
    child: Container(width: 80.0, height: 80.0, child: Image.asset('images/icon_hzw01.jpg')));

2. color & shadowColor

    color 对应 Widget 裁切的背景色,阴影效果是根据当前背景色展示,shadowColor 可以设置阴影颜色;

return PhysicalModel(
    color: Colors.teal.withOpacity(0.6),
    shape: isCircle ? BoxShape.circle : BoxShape.rectangle,
    clipBehavior: Clip.antiAlias,
    elevation: 6.0,
    shadowColor: isCircle ? Colors.yellow : Colors.deepOrange,
    borderRadius: BorderRadius.all(Radius.circular(20.0)),
    child: Container(width: 80.0, height: 80.0, color: Colors.pink.withOpacity(0.2)));

PhysicalShape

源码分析

const PhysicalShape({
    Key key,
    @required this.clipper,
    this.clipBehavior = Clip.none,
    this.elevation = 0.0,
    @required this.color,
    this.shadowColor = const Color(0xFF000000),
    Widget child,
})

    分析源码可得,PhysicalShapeClipPath 类似,均是通过 clipper 方式自定义裁切方式;

案例尝试

    小菜尝试裁切一个多边形图片,通过自定义 CustomClipper 来设置裁切样式;

return ClipPath(
    clipBehavior: Clip.antiAlias,
    clipper: PolygonClipper(10),
    child: Container(width: 80.0, height: 80.0, child: Image.asset('images/icon_hzw01.jpg')));

return PhysicalShape(
    color: Colors.transparent,
    clipBehavior: Clip.antiAlias,
    clipper: PolygonClipper(10),
    shadowColor: Colors.deepOrange,
    elevation: 6.0,
    child: Container(width: 80.0, height: 80.0, child: Image.asset('images/icon_hzw01.jpg')));

class PolygonClipper extends CustomClipper<Path> {
  final int num;
  PolygonClipper(this.num);

  @override
  Path getClip(Size size) {
    double radius = size.width * 0.5;
    Path _path = Path();
    var startX = size.width * 0.5 + radius * cos(2 * pi * 0 / num);
    var startY = size.height * 0.5 + radius * sin(2 * pi * 0 / num);
    _path.moveTo(startX, startY);
    for (var i = 1; i <= num; i++) {
      var newX = size.width * 0.5 + radius * cos(2 * pi * i / num);
      var newY = size.height * 0.5 + radius * sin(2 * pi * i / num);
      _path.lineTo(newX, newY);
    }
    _path.close();
    return _path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}


    PhysicalModel & PhysicalShape 案例源码


    小菜对于更深入的裁切方式还不够深入,Flutter 同时提供了对应带有动画效果的 AnimatedPhysicalModel;如有错误,请多多指导!

来源: 阿策小和尚
目录
相关文章
|
4天前
Flutter 组件(二)文本 与 输入框组件
Flutter 组件(二)文本 与 输入框组件
86 0
|
4天前
|
容器
Flutter 组件(一)组件概述
Flutter 组件(一)组件概述
62 0
|
3天前
|
存储 调度 安全
腾讯T2大牛亲自讲解,关于Flutter文本组件Widget的全面解读
腾讯T2大牛亲自讲解,关于Flutter文本组件Widget的全面解读
腾讯T2大牛亲自讲解,关于Flutter文本组件Widget的全面解读
|
3天前
|
设计模式 JavaScript 前端开发
flutter组件封装技巧
工厂函数不会自动调用,需要手动调用
12 3
|
4天前
|
前端开发 搜索推荐 UED
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
【4月更文挑战第30天】探索Flutter的高级UI组件,如`TabBar`、`Drawer`、`BottomSheet`,提升应用体验和美观度。使用高级组件能节省开发时间,提供内置交互逻辑和优秀视觉效果。示例代码展示了如何实现底部导航栏、侧边导航和底部弹出菜单。同时,自定义组件允许个性化设计和功能扩展,但也带来性能优化和维护挑战。参考Flutter官方文档和教程,深入学习并有效利用这些组件。
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
|
4天前
|
Dart
Flutter 中优雅切换应用主题的组件
【Flutter】使用adaptive_theme组件优雅切换应用主题:封装MaterialApp,支持light/dark/system模式,自定义色彩,保存选择,含调试按钮。安装配置、设置主题、监听切换、自定义颜色、读取配置步骤详细。代码示例与学习路径推荐。[查看完整教程](https://flutter.ducafecat.com/blog/flutter-app-theme-switch)
Flutter 中优雅切换应用主题的组件
|
8月前
|
人机交互
Flutter笔记 - ListTile组件及其应用
Flutter笔记 - ListTile组件及其应用
107 0
|
4天前
|
开发者 索引 容器
Flutter开发笔记:Flutter 布局相关组件
Flutter开发笔记:Flutter 布局相关组件
139 0
|
4天前
|
iOS开发
Flutter 组件(三)按钮类组件
Flutter 组件(三)按钮类组件
169 0
|
10月前
|
缓存 Dart 前端开发
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥
Flutter 界面开发中我们有几个痛点 : - 与设计师协作复用一套设计规范(figma) - 可视化的管理你的组件代码(基础组件、业务组件) - 不同设备尺寸测试你的组件 - 实时修改你的测试组件参数
4219 1
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥