star.dart 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import 'package:flutter/material.dart';
  2. class HTStarRating extends StatefulWidget {
  3. final double rating; // 当前分数
  4. final double maxRating; // 满分
  5. final int count; // 总共几颗心
  6. final double size; // 星星大小
  7. final Color defaultColor;
  8. final Color selectedColor;
  9. final Widget unselectedImage;
  10. final Widget selectedImage;
  11. HTStarRating({
  12. required this.rating, // 必填
  13. //选填, 初始默认值
  14. this.maxRating = 10,
  15. this.count = 5,
  16. this.size = 30,
  17. this.defaultColor = Colors.grey,
  18. this.selectedColor = Colors.red,
  19. Widget? unselectedImage,
  20. Widget? selectedImage,
  21. }):unselectedImage = unselectedImage?? Icon(
  22. Icons.star_border, color: defaultColor, size: size),
  23. selectedImage = selectedImage?? Icon(Icons.star, color: selectedColor,size: size);
  24. @override
  25. _HTStarRatingState createState() => _HTStarRatingState();
  26. }
  27. class _HTStarRatingState extends State<HTStarRating> {
  28. @override
  29. Widget build(BuildContext context) {
  30. return Stack(
  31. children: <Widget>[
  32. Row(
  33. mainAxisSize: MainAxisSize.min,
  34. children: buildDefaultStar()
  35. ),
  36. Row(
  37. mainAxisSize: MainAxisSize.min,
  38. children: buildSelectedStar()
  39. )
  40. ],
  41. );
  42. }
  43. /*
  44. * 创建默认的星星
  45. * */
  46. List<Widget> buildDefaultStar(){
  47. return List.generate(widget.count, (index) {
  48. return widget.unselectedImage;
  49. });
  50. }
  51. /*
  52. * 创建选中的星星
  53. * */
  54. List<Widget> buildSelectedStar() {
  55. // 创建stats
  56. List<Widget> starts = [];
  57. final star = widget.selectedImage;
  58. //构建满的start
  59. double oneValue = widget.maxRating / widget.count;
  60. int entireCount = (widget.rating / oneValue).floor(); //.floor() 向下取整
  61. for (var i = 0; i< entireCount ; i++){
  62. starts.add(star);
  63. }
  64. //构建部分start
  65. double leftWidth = ((widget.rating /oneValue)-entireCount)* widget.size;
  66. final halfStar = ClipRect(
  67. clipper: HTStartClipper(leftWidth),
  68. child: star
  69. );
  70. starts.add(halfStar);
  71. // 防止传入参数大于总分
  72. if (starts.length > widget.count){
  73. return starts.sublist(0,widget.count);
  74. }
  75. return starts;
  76. }
  77. }
  78. /*
  79. * 切割
  80. * */
  81. class HTStartClipper extends CustomClipper<Rect> {
  82. double width;
  83. HTStartClipper(this.width);
  84. @override
  85. Rect getClip(Size size) {
  86. return Rect.fromLTRB(0, 0, width, size.height);
  87. }
  88. @override
  89. bool shouldReclip(HTStartClipper oldClipper) {
  90. return oldClipper.width != this.width;
  91. }
  92. }