import 'package:flutter/material.dart'; class HTStarRating extends StatefulWidget { final double rating; // 当前分数 final double maxRating; // 满分 final int count; // 总共几颗心 final double size; // 星星大小 final Color defaultColor; final Color selectedColor; final Widget unselectedImage; final Widget selectedImage; HTStarRating({ required this.rating, // 必填 //选填, 初始默认值 this.maxRating = 10, this.count = 5, this.size = 30, this.defaultColor = Colors.grey, this.selectedColor = Colors.red, Widget? unselectedImage, Widget? selectedImage, }):unselectedImage = unselectedImage?? Icon( Icons.star_border, color: defaultColor, size: size), selectedImage = selectedImage?? Icon(Icons.star, color: selectedColor,size: size); @override _HTStarRatingState createState() => _HTStarRatingState(); } class _HTStarRatingState extends State { @override Widget build(BuildContext context) { return Stack( children: [ Row( mainAxisSize: MainAxisSize.min, children: buildDefaultStar() ), Row( mainAxisSize: MainAxisSize.min, children: buildSelectedStar() ) ], ); } /* * 创建默认的星星 * */ List buildDefaultStar(){ return List.generate(widget.count, (index) { return widget.unselectedImage; }); } /* * 创建选中的星星 * */ List buildSelectedStar() { // 创建stats List starts = []; final star = widget.selectedImage; //构建满的start double oneValue = widget.maxRating / widget.count; int entireCount = (widget.rating / oneValue).floor(); //.floor() 向下取整 for (var i = 0; i< entireCount ; i++){ starts.add(star); } //构建部分start double leftWidth = ((widget.rating /oneValue)-entireCount)* widget.size; final halfStar = ClipRect( clipper: HTStartClipper(leftWidth), child: star ); starts.add(halfStar); // 防止传入参数大于总分 if (starts.length > widget.count){ return starts.sublist(0,widget.count); } return starts; } } /* * 切割 * */ class HTStartClipper extends CustomClipper { double width; HTStartClipper(this.width); @override Rect getClip(Size size) { return Rect.fromLTRB(0, 0, width, size.height); } @override bool shouldReclip(HTStartClipper oldClipper) { return oldClipper.width != this.width; } }