https://blog.csdn.net/ITxiaodong/article/details/105029358
文章目錄
參考:
裁剪布局
Flutter中提供了一些剪裁widget,如下表格。
widget 作用
ClipRect 將 child 剪裁為給定的矩形大小
ClipRRect 將 child 剪裁為圓角矩形
ClipOval 如果 child 為正方形時剪裁之后是圓形,如果 child 為矩形時,剪裁之后為橢圓形
ClipPath 將 child 按照給定的路徑進行裁剪
CustomClipper 並不是一個widget,但是使用CustomClipper可以繪制出任何我們想要的形狀
ClipRect
將 child 剪裁為給定的矩形大小
查看構造函數支持哪些字段:
const ClipRect({
Key key,
this.clipper, // CustomClipper 對象,如果為空,則裁剪區域為 child 指定的大小
this.clipBehavior = Clip.hardEdge, // 裁剪的方式, 不能為 null 或者 Clip.none
Widget child // 子布局
}
)
clipBehavior可選值有:none, hardEdge, antiAlias, antiAliasWithSaveLayer
none:不裁剪
hardEdge:裁剪但不應用抗鋸齒,裁剪速度比none模式慢一點,但比其他方式快。
antiAlias:裁剪而且抗鋸齒,以實現更平滑的外觀。裁剪速度比antiAliasWithSaveLayer快,比hardEdge慢。
antiAliasWithSaveLayer:帶有抗鋸齒的剪輯,並在剪輯之后立即保存saveLayer。
代碼實現:
Column(
children: <Widget>[
Container(
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm'
),
),
SizedBox(
height: 30,
),
ClipRect(
child: Container(
height: 150,
width: 150,
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm',
fit: BoxFit.cover,
),
),
)
],
)
偽代碼:
Column(
children: <Widget>[
Container(
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm'
),
),
SizedBox(
height: 30,
),
ClipRRect(
borderRadius: BorderRadius.circular(20),// 圓角半徑
child: Container(
height: 150,
width: 150,
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm',
fit: BoxFit.cover,
),
),
),
],
)
ClipOval

如果 child 為正方形時剪裁之后是圓形,如果 child 為矩形時,剪裁之后為橢圓形。
構造函數中的字段同ClipRect。
偽代碼:
Column(
children: <Widget>[
Container(
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm'
),
),
SizedBox(
height: 30,
),
ClipOval(// 寬高不一致為,裁剪后為橢圓形
child: Container(
height: 100,
width: 150,
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm',
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 30,
),
ClipOval(// 寬高一致為,裁剪后為圓形
child: Container(
height: 100,
width: 100,
child: Image.network(
'https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm',
fit: BoxFit.cover,
),
),
),
],
)
ClipPath 及 CustomClipper

ClipPath會將 child 按照給定的路徑進行裁剪,CustomClipper可以繪制出任何我們想要的形狀
實現的效果:實戰項目源碼可在 Flutter-WanAndroid 中查看。
上方的這種效果可以通過ClipPath+CustomClipper實現。
主要思路是通過CustomClipper實現自定義的斜線效果然后將結果傳遞給ClipPath構造函數中的clipper字段。
我們先來看看CustomClipper這個抽象類。

在源碼中可以看到getClip方法就是獲取裁剪的區域。我們可以在這個方法中繪制出斜對角效果。
偽代碼實現如下:
class _CustomClipperTestPageState extends State<CustomClipperTestPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ClipPath、CustomClipper'),
),
body: Column(children: <Widget>[
Stack(
children: <Widget>[
ClipPath(
clipper:
TopBarClipper(MediaQuery.of(context).size.width, 200.0),
child: Container(// 主題色填充 child
width: double.infinity,
height: 240.0,
color: Theme.of(context).primaryColor,
),
),
// 名字
Padding(
padding: EdgeInsets.only(top: 40.0),
child: Center(
child: Text(
'龍衣',
style: TextStyle(fontSize: 30.0, color: Colors.white),
)),
),
// 圓形頭像
Container(
margin: EdgeInsets.only(top: 100.0),
child: Center(
child: Container(
width: 100.0,
height: 100.0,
child: ClipOval(
child: Image.network(
"https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/389e31d03d36465d8acd9939784df6f0.jpg!sswm",
fit: BoxFit.fill,
)))),
),
],
),
]));
}
}
/// 頂部斜對角欄裁剪
class TopBarClipper extends CustomClipper<Path> {
// 寬高
double width;
double height;
/// 構造函數,接收傳遞過來的寬高
TopBarClipper(this.width, this.height);
/// 獲取剪裁區域的接口
/// 返回斜對角的圖形 path
@override
Path getClip(Size size) {
Path path = Path();
path.moveTo(0.0, 0.0);
path.lineTo(width, 0.0);
// path 斜線效果
path.lineTo(width, height / 2);
path.lineTo(0.0, height);
path.close();
return path;
}
/// 接口決定是否重新剪裁
/// 如果在應用中,剪裁區域始終不會發生變化時應該返回 false,這樣就不會觸發重新剪裁,避免不必要的性能開銷。
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
完~
————————————————
版權聲明:本文為CSDN博主「_龍衣」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/ITxiaodong/article/details/105029358
