Flutter学习笔记 -- 5星评级组件


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 _getUnSelectStars() {
    return List.generate(this.count, (index) {
      return Icon(Icons.star_outline_rounded,size: size,color: unSelectColor,);
    });
  }

  // 填充星星
  List _getSelectStars() {
    return List.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 {
  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;
  }
}


你可能感兴趣的:(Flutter学习笔记 -- 5星评级组件)