【问题标题】:Dynamic filled star in flutter动态填充的星星在颤动
【发布时间】:2022-12-22 22:00:44
【问题描述】:

我正在尝试创建一个可以从左侧动态填充的星级评分组件。 到目前为止,我可以使用自定义画家创建一个粗糙的星星。

class StarPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    double w = size.width;
    double h = size.height;

    Path path = Path()
      ..moveTo(0, (2 * h) / 5)
      ..lineTo(w, (2 * h) / 5)
      ..lineTo(w / 5, h)
      ..lineTo(w / 2, 0)
      ..lineTo((4 * w) / 5, h)
      ..lineTo(0, (2 * h) / 5)
      ..close();

    Paint fillPaint = Paint()
      ..style = PaintingStyle.fill
      ..color = Colors.black;

    // canvas.drawPath(path, paint);
    canvas.drawPath(path, fillPaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

但是我无法弄清楚如何将其中的一部分显示为已填充。到目前为止,我已经使用了一个 +2 大小的双堆栈作为边框,并使用了一个带有线性渐变的着色器蒙版来显示进度。

但是,如果不采用粗略的堆叠方式,是否可以做到这一点?

Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: SizedBox(
            height: starSize,
            width: starSize,
            child: Stack(
              fit: StackFit.expand,
              children: [
                DynamicStar(percent: 1.0),
                Center(
                  child: SizedBox(
                    width: starSize - 2,
                    height: starSize - 2,
                    child: DynamicStar(percent: 0.8),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

class DynamicStar extends StatelessWidget {
  final double percent;
  const DynamicStar({Key? key, required this.percent}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ShaderMask(
      blendMode: BlendMode.srcATop,
      shaderCallback: (bounds) {
        return LinearGradient(
          tileMode: TileMode.clamp,
          colors: [Colors.black, Colors.white],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          stops: [percent, percent],
        ).createShader(bounds);
      },
      child: CustomPaint(painter: StarPainter()),
    );
  }
}

编辑:我正在努力学习,所以任何关于如何修复我的代码或 sn-ps 的线索都会帮助我更好。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    请参考以下链接

    https://pub.dev/packages/smooth_star_rating

    要么

    https://pub.dev/packages/flutter_rating_bar

    Smooth star rating example
    
    import 'package:flutter/material.dart';
    import 'package:smooth_star_rating/smooth_star_rating.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      var rating = 1.0;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Star rating',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
                child: SmoothStarRating(
              rating: rating,
              isReadOnly: false,
              size: 80,
              filledIconData: Icons.star,
              halfFilledIconData: Icons.star_half,
              defaultIconData: Icons.star_border,
              starCount: 5,
              allowHalfRating: true,
              spacing: 2.0,
              onRated: (value) {
                print("rating value -> $value");
               
              },
            )),
          ),
        );
      }
    }
    
    

    【讨论】:

    • 我确实提到过,它使用 Icons.star 并且不适用于动态值,对吗?因为它受图像的限制。它只能显示全,半或空。
    • 您可以在 SmoothStarRating 中将动态值分配给评分,将星星数分配给 starCount 属性
    • 是的,但它只会显示半颗星,对吗?它可以在 1/4 或除 1/2 以外的任何其他分数处显示星星吗?
    • pub.dev/packages/flutter_rating_bar。对于 1/4 或 3.6 等评级,您可以试试这个包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2015-12-18
    • 2021-04-04
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多