Flutter 通过Clipper实现各种自定义形状的示例代码
本文介绍了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, ), );
ContainerDecoration装饰形状
通过BoxShape.circle实现圆形图片
Container( width:120.0, height:120.0, decoration:BoxDecoration( shape:BoxShape.circle, image:DecorationImage( image:AssetImage( Config.assets_avatar_1, ), ), ) );
通过BorderRadius实现圆形图片
Container( width:120.0, height: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, ), ), ); enumClipperPosition{ LeftTop, RightTop, } classTriangleClipperextendsCustomClipper{ finalClipperPositionposition; TriangleClipper(this.position); @override PathgetClip(Sizesize){ finalpath=Path(); path.lineTo(0.0,0.0); if(position==ClipperPosition.LeftTop){ path.lineTo(size.width,0.0); path.lineTo(size.width,size.height); }elseif(position==ClipperPosition.RightTop){ path.lineTo(size.width,0.0); path.lineTo(0.0,size.height); } path.close(); returnpath; } @override boolshouldReclip(CustomClipperoldClipper){ returnfalse; } }
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_RectClipperextendsCustomClipper{ ///Removesideofsize finaldoubleremoveSize; _RectClipper(this.removeSize); @override RectgetClip(Sizesize){ returnnewRect.fromLTRB( removeSize, removeSize, size.width-removeSize, size.height-removeSize, ); } @override boolshouldReclip(CustomClipper oldClipper){ returnfalse; } }
ClipRRect圆角矩形剪裁
ClipRRect( borderRadius:BorderRadius.all(Radius.circular(16.0)), child:Image.asset( Config.assets_avatar_1, fit:BoxFit.fill, width:120.0, height:120.0, ), );
StarRating(CustomPaint)评分控件
评分控件UI图
实现方案
使用CustomPaint结合ClipPath画出单个五角星;
- 使用Stack渲染两层画面
- 背景层,一排灰色五角星 前景层,一排亮色五角星,并使用ClipRect截取一定Width
实现代码
classStarRatingDemoextendsStatefulWidget{ @override _StarRatingDemoStatecreateState()=>_StarRatingDemoState(); } class_StarRatingDemoStateextendsState{ ///ClipPathStarRating _buildClipPathStarRating(doublerate,intcount){ returnContainer( padding:EdgeInsets.fromLTRB(24.0,16.0,24.0,0.0), child:StaticRatingBar( size:50.0, rate:rate, count:count, ), ); } @override Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar( centerTitle:true, title:Text('StarRating'), ), body:ListView( physics:BouncingScrollPhysics(), children: [ //_buildClipPathStarRating(1.0,1), _buildClipPathStarRating(0.5,5), _buildClipPathStarRating(2.0,5), _buildClipPathStarRating(3.0,5), _buildClipPathStarRating(4.0,5), _buildClipPathStarRating(5.0,5), _buildClipPathStarRating(5.5,6), SizedBox(height:16.0), ], ), ); } } classStaticRatingBarextendsStatelessWidget{ ///Numberofstars finalintcount; ///Initrate finaldoublerate; ///Sizeofthestarts finaldoublesize; finalColorcolorLight; finalColorcolorDark; StaticRatingBar({ this.rate=5, this.colorLight=constColor(0xFF1E88E5), this.colorDark=constColor(0xFFEEEEEE), this.count=5, this.size=60, }); WidgetbuildDarkStar(){ returnSizedBox( width:size*count, height:size, child:CustomPaint( painter:_PainterStars( count:count, color:colorDark, strokeWidth:0.0, size:this.size/2, style:PaintingStyle.fill, ), ), ); } WidgetbuildLightStar(){ returnClipRect( clipper:_RatingBarClipper(rate*size), child:SizedBox( height:size, width:size*count, child:CustomPaint( painter:_PainterStars( count:count, strokeWidth:0.0, color:colorLight, size:this.size/2, style:PaintingStyle.fill, ), ), ), ); } @override Widgetbuild(BuildContextcontext){ returnStack( children: [ buildDarkStar(), buildLightStar(), ], ); } } class_RatingBarClipperextendsCustomClipper { finaldoublewidth; _RatingBarClipper(this.width); @override RectgetClip(Sizesize){ returnRect.fromLTRB(0.0,0.0,width,size.height); } @override boolshouldReclip(_RatingBarClipperoldClipper){ returnfalse; } } class_PainterStarsextendsCustomPainter{ finaldoublesize; finalintcount; finalColorcolor; finalPaintingStylestyle; finaldoublestrokeWidth; _PainterStars({ this.size, this.count, this.color, this.strokeWidth, this.style, }); doubledegree2Radian(intdegree){ return(pi*degree/180); } PathcreateStarPath(doubleradius,Pathpath){ doubleradian=degree2Radian(36); doubleradiusIn=(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), (radius-radius*sin(radian/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)), (radius+radius*cos(radian)), ); path.lineTo( (radius*cos(radian/2)-radiusIn*cos(radian/2)), (radius+radiusIn*sin(radian/2)), ); path.lineTo(0.0,(radius-radius*sin(radian/2))); path.lineTo( (radius*cos(radian/2)-radiusIn*sin(radian)), (radius-radius*sin(radian/2)), ); path.lineTo((radius*cos(radian/2)),0.0); returnpath; } @override voidpaint(Canvascanvas,Sizesize){ Paintpaint=Paint(); paint.strokeWidth=strokeWidth; paint.color=color; paint.style=style; Pathpath=Path(); doubleoffset=strokeWidth>0?strokeWidth+2:0.0; path=createStarPath(this.size-offset,path); for(inti=0;i 0){ path=path.shift(Offset(offset,offset)); } path.close(); canvas.drawPath(path,paint); } @override boolshouldRepaint(_PainterStarsoldDelegate){ returnoldDelegate.size!=this.size; } }
代码地址
https://github.com/smiling1990/FlutterClipper
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。