TreeviewCopyright © aleen42 all right reserved, powered by aleen42
概述
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 搭配使用:
- CustomPaint
- CustomSingleChildLayout
- CustomMultiChildLayout
- Align and Center
- OverflowBox
- SizedOverflowBox
示例:
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
路径剪切有两种方式,一种是使用系统自带的路径,一种是自定义路径
自带路径
使用系统自带的路径主要是通过 ClipPath
的 shap
方法:
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;
}
}
效果如下: