这篇文章将为大家详细讲解有关怎么在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, 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,
),
),
);
enum ClipperPosition {
LeftTop,
RightTop,
}
class TriangleClipper extends CustomClipper {
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{ /// 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 oldClipper) { return false; } }
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, ), );
Star Rating(CustomPaint) 评分控件
评分控件 UI图
实现方案
使用CustomPaint结合ClipPath画出单个五角星;
使用Stack渲染两层画面
背景层,一排灰色五角星 前景层,一排亮色五角星,并使用ClipRect截取一定Width
实现代码
class StarRatingDemo extends StatefulWidget {
@override
_StarRatingDemoState createState() => _StarRatingDemoState();
}
class _StarRatingDemoState extends State {
/// 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: [
// _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),
],
),
);
}
}
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,
strokeWidth: 0.0,
color: colorLight,
size: this.size / 2,
style: PaintingStyle.fill,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
buildDarkStar(),
buildLightStar(),
],
);
}
}
class _RatingBarClipper extends CustomClipper {
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),
(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);
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;
}
} 关于怎么在Flutter中利用Clipper自定义形状就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。