Flutter 中怎么實現(xiàn)一個裁剪類組件,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
ClipRect組件使用矩形裁剪子組件,通常情況下,ClipRect作用于CustomPaint
、
CustomSingleChildLayout
、
CustomMultiChildLayout
、
Align
、
Center
、
OverflowBox
、
SizedOverflowBox
組件,例如ClipRect作用于Align,可以僅顯示上半部分,代碼如下:
ClipRect( child: Align( alignment: Alignment.topCenter, heightFactor: 0.5, child: Container( height: 150, width: 150, child: Image.asset( 'images/1.png', fit: BoxFit.cover, ), ), ), )
全圖效果:
裁剪效果:
clipper
參數(shù)定義裁剪規(guī)則,下面具體介紹。
clipBehavior
參數(shù)定義了裁剪的方式,只有子控件超出父控件的范圍才有裁剪的說法,各個方式說明如下:
none:不裁剪,系統(tǒng)默認值,如果子組件不超出邊界,此值沒有任何性能消耗。
hardEdge:裁剪但不應(yīng)用抗鋸齒,速度比none
慢一點,但比其他方式快。
antiAlias:裁剪而且抗鋸齒,此方式看起來更平滑,比antiAliasWithSaveLayer
快,比hardEdge
慢,通常用于處理圓形和弧形裁剪。
antiAliasWithSaveLayer:裁剪、抗鋸齒而且有一個緩沖區(qū),此方式很慢,用到的情況比較少。
ClipRRect組件可以對子組件進行圓角裁剪,默認圓角半徑為0,注意ClipRRect有2個R,不是上面介紹的ClipRect。
用法如下:
ClipRRect( borderRadius: BorderRadius.circular(20), child: Container( height: 150, width: 150, child: Image.asset( 'images/1.png', fit: BoxFit.cover, ), ), )
效果如圖:
ClipOval裁剪為橢圓形,橢圓形的大小為正切父組件,因此如果父組件為正方形,切出來是圓形,用法如下:
ClipOval( child: Container( height: 150, width: 250, child: Image.asset( 'images/1.png', fit: BoxFit.cover, ), ), )
效果如下:
ClipPath組件根據(jù)路徑進行裁剪,我們自定義裁剪路徑也可以使用系統(tǒng)提供的,用法如下:
ClipPath.shape( shape: StadiumBorder(), child: Container( height: 150, width: 250, child: Image.asset( 'images/1.png', fit: BoxFit.cover, ), ), )
shape
參數(shù)是ShapeBorder類型,系統(tǒng)已經(jīng)定義了很多形狀,介紹如下:
RoundedRectangleBorder:圓角矩形
ContinuousRectangleBorder:直線和圓角平滑連續(xù)的過渡,和RoundedRectangleBorder相比,圓角效果會小一些。
StadiumBorder:類似于足球場的形狀,兩端半圓。
BeveledRectangleBorder:斜角矩形。效果如圖:
CircleBorder:圓形。
CustomClipper并不是一個組件,而是一個abstract
(抽象)類,使用CustomClipper可以繪制出任何我們想要的形狀,比如三角形,代碼如下:
@override Widget build(BuildContext context) { return Center( child: ClipPath( clipper: TrianglePath(), child: Container( height: 150, width: 250, child: Image.asset( 'images/1.png', fit: BoxFit.cover, ), ), ), ); }
自定義TrianglePath代碼如下:
class TrianglePath extends CustomClipper<Path>{ @override Path getClip(Size size) { var path = Path(); path.moveTo(size.width/2, 0); path.lineTo(0, size.height); path.lineTo(size.width, size.height); return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) { return true; } }
效果如下:
我們還可以繪制五角星,代碼如下:
class StarPath extends CustomClipper<Path> { StarPath({this.scale = 2.5}); final double scale; double perDegree = 36; /// 角度轉(zhuǎn)弧度公式 double degree2Radian(double degree) { return (pi * degree / 180); } @override Path getClip(Size size) { var R = min(size.width / 2, size.height / 2); var r = R / scale; var x = size.width / 2; var y = size.height / 2; var path = Path(); path.moveTo(x, y - R); path.lineTo(x - sin(degree2Radian(perDegree)) * r, y - cos(degree2Radian(perDegree)) * r); path.lineTo(x - sin(degree2Radian(perDegree * 2)) * R, y - cos(degree2Radian(perDegree * 2)) * R); path.lineTo(x - sin(degree2Radian(perDegree * 3)) * r, y - cos(degree2Radian(perDegree * 3)) * r); path.lineTo(x - sin(degree2Radian(perDegree * 4)) * R, y - cos(degree2Radian(perDegree * 4)) * R); path.lineTo(x - sin(degree2Radian(perDegree * 5)) * r, y - cos(degree2Radian(perDegree * 5)) * r); path.lineTo(x - sin(degree2Radian(perDegree * 6)) * R, y - cos(degree2Radian(perDegree * 6)) * R); path.lineTo(x - sin(degree2Radian(perDegree * 7)) * r, y - cos(degree2Radian(perDegree * 7)) * r); path.lineTo(x - sin(degree2Radian(perDegree * 8)) * R, y - cos(degree2Radian(perDegree * 8)) * R); path.lineTo(x - sin(degree2Radian(perDegree * 9)) * r, y - cos(degree2Radian(perDegree * 9)) * r); path.lineTo(x - sin(degree2Radian(perDegree * 10)) * R, y - cos(degree2Radian(perDegree * 10)) * R); return path; } @override bool shouldReclip(StarPath oldClipper) { return oldClipper.scale != this.scale; } }
scale
參數(shù)表示間隔的點到圓心的縮放比例,五角星效果如下:
下面用動畫動態(tài)設(shè)置scale
,代碼如下:
class StartClip extends StatefulWidget { @override State<StatefulWidget> createState() => _StartClipState(); } class _StartClipState extends State<StartClip> with SingleTickerProviderStateMixin { AnimationController _controller; Animation _animation; @override void initState() { _controller = AnimationController(duration: Duration(seconds: 2), vsync: this) ..addStatusListener((status) { if (status == AnimationStatus.completed) { _controller.reverse(); } else if (status == AnimationStatus.dismissed) { _controller.forward(); } }); _animation = Tween(begin: 1.0, end: 4.0).animate(_controller); _controller.forward(); super.initState(); } @override Widget build(BuildContext context) { return Center( child: AnimatedBuilder( animation: _animation, builder: (context, child) { return ClipPath( clipper: StarPath(scale: _animation.value), child: Container( height: 150, width: 150, color: Colors.red, ), ); }), ); } }
看完上述內(nèi)容,你們掌握Flutter 中怎么實現(xiàn)一個裁剪類組件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!
本文題目:Flutter中怎么實現(xiàn)一個裁剪類組件-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://chinadenli.net/article6/doipig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、域名注冊、網(wǎng)站導(dǎo)航、品牌網(wǎng)站建設(shè)、做網(wǎng)站、App設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容