class StartRating extends StatefulWidget {
final int count; //当前几颗星
final double rating; //当前分数
final double maxRating; //满分是多少
final double size;
//展示多少颗星
StartRating({
required this.rating,
this.maxRating = 10,
this.count = 5,
this.size = 30,
});
@override
_StartRatingState createState() => _StartRatingState();
}
class _StartRatingState extends State<StartRating> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: Container(
width: 300,
color: Colors.yellow,
child: Stack(
children: [
Row(mainAxisSize: MainAxisSize.min, children: fullMarksStar(),),
Row(mainAxisSize: MainAxisSize.min, children: getShow(),),
Positioned(child: Text('评分 ${widget.rating}分',),right: 50,top: 5,)
],
),
),
);
}
//定义一个方法
List<Widget> fullMarksStar() {
return List.generate(widget.count, (index) {
return Icon(Icons.star_border_outlined, size: widget.size,);
});
}
List<Widget> getShow() {
//startcount 是得到 总分 / 星个数的,得出每个星所占的份量
var starcount = widget.maxRating / widget.count;
//用当前的 分数 / 每个星的份量,然后往下取整得到几个星
var scount = (widget.rating / starcount).floor();
//定义一个值,来决定小数部分的裁剪的量
var c = (widget.rating / starcount - scount) * widget.size;
final stars = Icon(Icons.star, color: Colors.red, size: widget.size,);
List<Widget> star = [];
for (var i = 0; i < scount; i ++) {
star.add(stars);
}
//小数点部分,需要进行裁剪最后添加到列表当中去要使用到一个组件 ClipRect
star.add(ClipRect(child: stars,clipper: StarClipper(c),));
return star;
}
}
class StarClipper extends CustomClipper<Rect>{
double width;
StarClipper(this.width);
@override
getClip(Size size) {
// TODO: implement getClip
return Rect.fromLTRB(0, 0, this.width, size.height);
}
@override
bool shouldReclip(StarClipper oldClipper) {
// TODO: implement shouldReclip
return oldClipper.width != this.width;
}
}