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

老菜和尚 2021/3/5 20:11:21

小菜在学习过程中发现仅通过设置 **decoration** 是无法改变 **Container** 内部 **Widget** 样式的,一般我们会通过 **ClipX** 方式进行裁剪;而一旦涉及到 **Widget** 的裁剪,对于基础样式,通常会采用 **ClipOval / ClipRRect / ClipPath** 等方式,对于稍加复杂的样…
小菜在学习过程中发现仅通过设置 **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.rectangle** 和 **BoxShape.circle** 两种,分别对应 **ClipRRect** 和 **ClipOval**,而 **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,
})
分析源码可得,**PhysicalShape** 与 **ClipPath** 类似,均是通过 **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 {
  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 oldClipper) => true;
}


[**PhysicalModel & PhysicalShape 案例源码**] 
github.com/ACE-YANGCE/FlutterApp/blob/master/lib/page/physical_model_page.dart

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

> 来源: 阿策小和尚

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Flutter 116: 图解 PhysicalModel & PhysicalShape 裁切小组件]http://www.zyiz.net/tech/detail-152422.html

上一篇:【邀请有礼】全球视频云创新挑战赛邀请有礼:参与 100% 获得 “壕” 礼,更有机会获得 JBL 音箱、Cherry 机械键盘

下一篇:PyTorch 1.8 发布,支持 AMD,优化大规模训练

赞(0)

共有 条评论 网友评论

验证码: 看不清楚?
    关注微信小程序
    程序员编程王-随时随地学编程

    扫描二维码或查找【程序员编程王】

    可以随时随地学编程啦!

    技术文章导航 更多>
    扫一扫关注最新编程教程