Flutter實(shí)現(xiàn): 5星評(píng)分的展示的小組件 -- 支持不同數(shù)量的星星名斟、顏色、大小等
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星評(píng)級(jí)"),),
body: Center(child: XMStartRating(rating: 8.9,),),
),
);
}
}
/// 5星評(píng)分的展示的小組件 -- 支持不同數(shù)量的星星孝鹊、顏色、大小等
class XMStartRating extends StatelessWidget {
final int count; // 星星的數(shù)量,默認(rèn)是5個(gè)
final double rating; // 獲得的分?jǐn)?shù)
final double totalRating; // 總分?jǐn)?shù)
final Color unSelectColor; // 未選中的顏色
final Color selectColor; // 選中的顏色
final double size; // 星星的大小
final double spacing; // 星星間的間隙
// 自定義構(gòu)造函數(shù)
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(),
);
}
// 獲取針對(duì)整個(gè)選中的星星裁剪的組件
Widget getSelectStarWidget() {
// 應(yīng)該展示幾個(gè)星星 --- 例如:4.6個(gè)星星
final double showStarCount = this.count * (this.rating/this.totalRating);
final int fillStarCount = showStarCount.floor();// 滿星的數(shù)量
final double halfStarCount = showStarCount - fillStarCount; // 半星的數(shù)量
// 最終需要裁剪的寬度
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;
}
}