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;i0){
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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。