![](https://img.haomeiwen.com/i1901942/464d5a69dd45e8e3.png)
Flutter实现: 5星评分的展示的小组件 -- 支持不同数量的星星、颜色、大小等
import 'package:flutter/material.dart';
main() {
return runApp(XMHomePage());
}
class XMHomePage extends StatelessWidget {
const XMHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("5星评级"),),
body: Center(child: XMStartRating(rating: 8.9,),),
),
);
}
}
/// 5星评分的展示的小组件 -- 支持不同数量的星星、颜色、大小等
class XMStartRating extends StatelessWidget {
final int count; // 星星的数量,默认是5个
final double rating; // 获得的分数
final double totalRating; // 总分数
final Color unSelectColor; // 未选中的颜色
final Color selectColor; // 选中的颜色
final double size; // 星星的大小
final double spacing; // 星星间的间隙
// 自定义构造函数
XMStartRating({
required this.rating,
this.totalRating = 10,
this.unSelectColor = Colors.grey,
this.selectColor = Colors.red,
this.size = 30,
this.count = 5,
this.spacing = 2,
});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.green,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [
getUnSelectStarWidget(),
getSelectStarWidget()
],
),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Text("${this.rating}分",style: TextStyle(fontSize: 20),),
),
],
),
);
}
// 获取背景:未填充的星星
List<Widget> _getUnSelectStars() {
return List<Widget>.generate(this.count, (index) {
return Icon(Icons.star_outline_rounded,size: size,color: unSelectColor,);
});
}
// 填充星星
List<Widget> _getSelectStars() {
return List<Widget>.generate(this.count, (index) {
return Icon(Icons.star, size: size, color: selectColor,);
});
}
// 获取背景星星的组件
Widget getUnSelectStarWidget() {
return Wrap(
spacing: this.spacing,
alignment: WrapAlignment.spaceBetween,
children: _getUnSelectStars(),
);
}
// 获取针对整个选中的星星裁剪的组件
Widget getSelectStarWidget() {
// 应该展示几个星星 --- 例如:4.6个星星
final double showStarCount = this.count * (this.rating/this.totalRating);
final int fillStarCount = showStarCount.floor();// 满星的数量
final double halfStarCount = showStarCount - fillStarCount; // 半星的数量
// 最终需要裁剪的宽度
final double clipWith = fillStarCount*(this.size + this.spacing) + halfStarCount*this.size;
return ClipRect(
clipper: XMStarClipper(clipWith),
child: Container(
child: Wrap(
spacing: this.spacing,
alignment: WrapAlignment.spaceBetween,
children: _getSelectStars(),
),
),
);
}
}
// 获取裁剪过的星星
class XMStarClipper extends CustomClipper<Rect> {
double clipWidth;
XMStarClipper(this.clipWidth);
@override
Rect getClip(Size size) {
return Rect.fromLTRB(0, 0, clipWidth, size.height);
}
@override
bool shouldReclip(XMStarClipper oldClipper) {
// TODO: implement shouldReclip
return clipWidth != oldClipper.clipWidth;
}
}
网友评论