Flutter-评分组件

90 阅读1分钟

Flutter-评分组件

image-20221014110806099

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
​
class MJYStartRating extends StatefulWidget{
  // const MJYStartRating({Key? key}) : super(key: key);
  final double rating;
  final double maxRating;
  final int count;
  final double size;
  final Color unselectedColor;
  final Color selectedColor;
  final Widget unselectedImage;
  final Widget selectedImage;
​
  MJYStartRating({
    required this.rating,
    this.maxRating = 10,
    this.count = 5,
    this.size = 30,
    this.unselectedColor  = Colors.grey,
    this.selectedColor = Colors.red,
    Widget? unselectedImage,
    Widget? selectedImage,
  }):unselectedImage =  unselectedImage ?? Icon(Icons.star_border,color:unselectedColor, size: size,),
        selectedImage = selectedImage ?? Icon(Icons.star,color:selectedColor, size: size,);
  @override
  State<StatefulWidget> createState()=> _MJYStartRatingState();
}
class _MJYStartRatingState extends State<MJYStartRating>{
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Row(mainAxisSize: MainAxisSize.min, children:buildUnselectedStar()),
        Row(mainAxisSize: MainAxisSize.min, children: buildSelectedStar()),
      ],
    );
  }
​
  List<Widget> buildUnselectedStar() {
    return List.generate(widget.count, (index) {
      return widget.unselectedImage;
    });
  }
  List<Widget> buildSelectedStar() {
    // 1.创建starts
    List<Widget> stars = [];
    final star =  widget.selectedImage;
    // 2. 构建满的stat
    double oneStarValue = widget.maxRating / widget.count;
    int fullStarCount = (widget.rating/ oneStarValue).floor();
    for (var  i = 0;  i<fullStarCount;i++){
      stars.add(star);
    }
    // 3.构建部分填充stat
    double  leftWidth  = (widget.rating - oneStarValue * fullStarCount) / oneStarValue * widget.size;
    print(leftWidth);
    final partStar = ClipRect(
      clipper: MJYStarClipper(width: leftWidth),
      child: star,
    );
    stars.add(partStar);
    if(stars.length > widget.count){
      return stars.sublist(0,widget.count);
    }
    return stars;
  }
}
​
class MJYStarClipper extends CustomClipper<Rect> {
  double width;
  MJYStarClipper({required this.width} );
​
  @override
  Rect getClip(Size size) {
    print("size = $width");
    return Rect.fromLTRB(0, 0, width, size.height);
  }
​
  @override
  bool shouldReclip(covariant MJYStarClipper oldClipper) {
    return oldClipper.width != width;
    // return true;
  }
​
}

效果:如果输入9分的效果

image-20221014110806099