dart - 如何正确创建评分星条?

我正在尝试为用户评分创建一个星条,下图来自 Play 商店以说明我要实现的目标:

我已经能够实现以下功能,正如你所看到的那样,但是当我查看我的代码时,我觉得必须有一个更聪明的方法来做到这一点,而真正令人讨厌的部分是 IconButton 命中区域略微上移,因此当您触摸实际的星星时,它不会注册为触摸事件(即:您必须将目标瞄准高于按钮的位置才能进行触摸要注册,这会导致糟糕的用户体验)你可以通过在我点击任何星星时留意飞溅效果来检查我的意思:

var _myColorOne = Colors.grey;
  var _myColorTwo = Colors.grey;
  var _myColorThree = Colors.grey;
  var _myColorFour = Colors.grey;
  var _myColorFive = Colors.grey;


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
     appBar: new AppBar(
       title: new Text("My Rating"),
     ),
      body:  new Center(
        child: new Container(
          height: 10.0,
          width: 500.0,
          child: new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new IconButton(icon: new Icon(Icons.star),
                  onPressed: ()=>setState((){
                    _myColorOne=Colors.orange;
                    _myColorTwo=null;
                    _myColorThree=null;
                    _myColorFour=null;
                    _myColorFive=null;
                }),color: _myColorOne,),
                new IconButton(icon: new Icon(Icons.star),
                  onPressed: ()=>setState((){
                    _myColorOne=Colors.orange;
                    _myColorTwo=Colors.orange;
                    _myColorThree=Colors.grey;
                    _myColorFour=Colors.grey;
                    _myColorFive=Colors.grey;
                }),color: _myColorTwo,),
                new IconButton(icon: new Icon(Icons.star), onPressed: ()=>setState((){
                  _myColorOne=Colors.orange;
                  _myColorTwo=Colors.orange;
                  _myColorThree=Colors.orange;
                  _myColorFour=Colors.grey;
                  _myColorFive=Colors.grey;
                }),color: _myColorThree,),
                new IconButton(icon: new Icon(Icons.star), onPressed: ()=>setState((){
                  _myColorOne=Colors.orange;
                  _myColorTwo=Colors.orange;
                  _myColorThree=Colors.orange;
                  _myColorFour=Colors.orange;
                  _myColorFive=Colors.grey;
                }),color: _myColorFour,),
                new IconButton(icon: new Icon(Icons.star), onPressed: ()=>setState((){
                  _myColorOne=Colors.orange;
                  _myColorTwo=Colors.orange;
                  _myColorThree=Colors.orange;
                  _myColorFour=Colors.orange;
                  _myColorFive=Colors.orange;
                }),color: _myColorFive,),
              ],

          ),
        ),
      ),
    );
  }

那么这里有什么更好的方法吗?

最佳答案

太多的重复和填充!呵呵

不管怎样,我就是这样做的。简单,可重复使用。 您可以在有点击和无点击的情况下使用它(无点击禁用波纹效果)。 半星也是。如果没有指定颜色,则使用原色填充星星。

typedef void RatingChangeCallback(double rating);

class StarRating extends StatelessWidget {
  final int starCount;
  final double rating;
  final RatingChangeCallback onRatingChanged;
  final Color color;

  StarRating({this.starCount = 5, this.rating = .0, this.onRatingChanged, this.color});

  Widget buildStar(BuildContext context, int index) {
    Icon icon;
    if (index >= rating) {
      icon = new Icon(
        Icons.star_border,
        color: Theme.of(context).buttonColor,
      );
    }
    else if (index > rating - 1 && index < rating) {
      icon = new Icon(
        Icons.star_half,
        color: color ?? Theme.of(context).primaryColor,
      );
    } else {
      icon = new Icon(
        Icons.star,
        color: color ?? Theme.of(context).primaryColor,
      );
    }
    return new InkResponse(
      onTap: onRatingChanged == null ? null : () => onRatingChanged(index + 1.0),
      child: icon,
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Row(children: new List.generate(starCount, (index) => buildStar(context, index)));
  }
}

然后你可以像这样使用它:

class Test extends StatefulWidget {
  @override
  _TestState createState() => new _TestState();
}

class _TestState extends State<Test> {
  double rating = 3.5;

  @override
  Widget build(BuildContext context) {
    return new StarRating(
      rating: rating,
      onRatingChanged: (rating) => setState(() => this.rating = rating),
    );
  }
}

https://stackoverflow.com/questions/46637566/

相关文章:

dart - Flutter TextField 自动完成覆盖

dart - 如何在我的 Flutter 应用程序中重置基本路由 - 即弹出任何路由并使用 Navi

dart - Flutter BottomNavigationBar 不能处理三个以上的项目

flutter - 如何在不同的屏幕尺寸上测试 Flutter 小部件?

dart - Flutter Firestore 服务器端时间戳

dart - flutter 导航器不工作

ios - 使用 Swift 创建 Flutter 项目

android-studio - 无法将 Flutter 项目迁移到 AndroidX

android - 在 flutter 中打开对话框时检测返回按钮按下

flutter - Flutter中如何实现自定义对话框?