Flutter 通過Clipper實現各種自定義形狀的示例程式碼
阿新 • • 發佈:2020-01-07
本文介紹了Flutter 通過Clipper實現各種自定義形狀的示例程式碼,分享給大家,具體如下:
ClipOval 圓形裁剪
ClipOval( child: SizedBox( width: 120.0,height: 120.0,child: Image.asset( Config.assets_avatar_1,),);
CircleAvatar 圓形頭像
CircleAvatar( radius: 60.0,backgroundImage: AssetImage( Config.assets_avatar_1,);
Container Decoration 裝飾形狀
通過BoxShape.circle實現圓形圖片
Container( width: 120.0,decoration: BoxDecoration( shape: BoxShape.circle,image: DecorationImage( image: AssetImage( Config.assets_avatar_1,) );
通過BorderRadius實現圓形圖片
Container( width: 120.0,decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(60.0)),image: DecorationImage( image: AssetImage( Config.assets_avatar_1,)
ClipPath 路徑剪裁
ClipPath( clipper: TriangleClipper(ClipperPosition.LeftTop),child: Container( width: 16.0,height: 16.0,decoration: BoxDecoration( color: Colors.blue,); enum ClipperPosition { LeftTop,RightTop,} class TriangleClipper extends CustomClipper<Path> { final ClipperPosition position; TriangleClipper(this.position); @override Path getClip(Size size) { final path = Path(); path.lineTo(0.0,0.0); if (position == ClipperPosition.LeftTop) { path.lineTo(size.width,0.0); path.lineTo(size.width,size.height); } else if (position == ClipperPosition.RightTop) { path.lineTo(size.width,0.0); path.lineTo(0.0,size.height); } path.close(); return path; } @override bool shouldReclip(CustomClipper oldClipper) { return false; } }
ClipRect 矩形剪裁
Container( alignment: Alignment.topCenter,color: Colors.transparent,child: Container( color: Colors.green,child: ClipRect( clipper: _RectClipper(20.0),child: Image.asset( Config.assets_avatar_1,width: 160.0,height: 160.0,fit: BoxFit.fill,); class _RectClipper extends CustomClipper<Rect> { /// Remove side of size final double removeSize; _RectClipper(this.removeSize); @override Rect getClip(Size size) { return new Rect.fromLTRB( removeSize,removeSize,size.width - removeSize,size.height - removeSize,); } @override bool shouldReclip(CustomClipper<Rect> oldClipper) { return false; } }
ClipRRect 圓角矩形剪裁
ClipRRect( borderRadius: BorderRadius.all(Radius.circular(16.0)),child: Image.asset( Config.assets_avatar_1,width: 120.0,);
Star Rating(CustomPaint) 評分控制元件
評分控制元件 UI圖
實現方案
使用CustomPaint結合ClipPath畫出單個五角星;
- 使用Stack渲染兩層畫面
- 背景層,一排灰色五角星 前景層,一排亮色五角星,並使用ClipRect擷取一定Width
實現程式碼
class StarRatingDemo extends StatefulWidget { @override _StarRatingDemoState createState() => _StarRatingDemoState(); } class _StarRatingDemoState extends State<StarRatingDemo> { /// ClipPath Star Rating _buildClipPathStarRating(double rate,int count) { return Container( padding: EdgeInsets.fromLTRB(24.0,16.0,24.0,0.0),child: StaticRatingBar( size: 50.0,rate: rate,count: count,); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true,title: Text('Star Rating'),body: ListView( physics: BouncingScrollPhysics(),children: <Widget>[ // _buildClipPathStarRating(1.0,1),_buildClipPathStarRating(0.5,5),_buildClipPathStarRating(2.0,_buildClipPathStarRating(3.0,_buildClipPathStarRating(4.0,_buildClipPathStarRating(5.0,_buildClipPathStarRating(5.5,6),SizedBox(height: 16.0),],); } } class StaticRatingBar extends StatelessWidget { /// Number of stars final int count; /// Init rate final double rate; /// Size of the starts final double size; final Color colorLight; final Color colorDark; StaticRatingBar({ this.rate = 5,this.colorLight = const Color(0xFF1E88E5),this.colorDark = const Color(0xFFEEEEEE),this.count = 5,this.size = 60,}); Widget buildDarkStar() { return SizedBox( width: size * count,height: size,child: CustomPaint( painter: _PainterStars( count: count,color: colorDark,strokeWidth: 0.0,size: this.size / 2,style: PaintingStyle.fill,); } Widget buildLightStar() { return ClipRect( clipper: _RatingBarClipper(rate * size),child: SizedBox( height: size,width: size * count,child: CustomPaint( painter: _PainterStars( count: count,color: colorLight,); } @override Widget build(BuildContext context) { return Stack( children: <Widget>[ buildDarkStar(),buildLightStar(),); } } class _RatingBarClipper extends CustomClipper<Rect> { final double width; _RatingBarClipper(this.width); @override Rect getClip(Size size) { return Rect.fromLTRB(0.0,0.0,width,size.height); } @override bool shouldReclip(_RatingBarClipper oldClipper) { return false; } } class _PainterStars extends CustomPainter { final double size; final int count; final Color color; final PaintingStyle style; final double strokeWidth; _PainterStars({ this.size,this.count,this.color,this.strokeWidth,this.style,}); double degree2Radian(int degree) { return (pi * degree / 180); } Path createStarPath(double radius,Path path) { double radian = degree2Radian(36); double radiusIn = (radius * sin(radian / 2) / cos(radian)) * 1.1; path.moveTo((radius * cos(radian / 2)),0.0); path.lineTo( (radius * cos(radian / 2) + radiusIn * sin(radian)),(radius - radius * sin(radian / 2)),); path.lineTo( (radius * cos(radian / 2) * 2),); path.lineTo( (radius * cos(radian / 2) + radiusIn * cos(radian / 2)),(radius + radiusIn * sin(radian / 2)),); path.lineTo( (radius * cos(radian / 2) + radius * sin(radian)),(radius + radius * cos(radian)),); path.lineTo((radius * cos(radian / 2)),(radius + radiusIn)); path.lineTo( (radius * cos(radian / 2) - radius * sin(radian)),); path.lineTo( (radius * cos(radian / 2) - radiusIn * cos(radian / 2)),); path.lineTo(0.0,(radius - radius * sin(radian / 2))); path.lineTo( (radius * cos(radian / 2) - radiusIn * sin(radian)),0.0); return path; } @override void paint(Canvas canvas,Size size) { Paint paint = Paint(); paint.strokeWidth = strokeWidth; paint.color = color; paint.style = style; Path path = Path(); double offset = strokeWidth > 0 ? strokeWidth + 2 : 0.0; path = createStarPath(this.size - offset,path); for (int i = 0; i < count - 1; i++) { path = path.shift(Offset(this.size * 2,0.0)); path = createStarPath(this.size - offset,path); } if (offset > 0) { path = path.shift(Offset(offset,offset)); } path.close(); canvas.drawPath(path,paint); } @override bool shouldRepaint(_PainterStars oldDelegate) { return oldDelegate.size != this.size; } }
程式碼地址
https://github.com/smiling1990/FlutterClipper
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。