Flutter 封装一个打星的东西

Flutter 封装一个打星的东西

star Widget组件

如果我们封装一个组件的话很明显我们的这个因该足够灵活

所以我们需要给它传很多的参数 其中只有分数是必填参数

  • rating: 分数 (必填参数)
  • maxRating: 满分
  • count: 准备有几颗星
  • star: 的大小
  • unselectedColor: 未选中的颜色
  • unselectedColor: 选中的颜色
  • unselectedImage: 自定义为选中的图片
  • selectedImage: 自定义选中的图片

这样它就会足够的灵活

同时也为了让他可以打出几点几个星的效果 我们需要做个 图片裁剪的功能

排布设置

我们的星星是水平排布的 所以我们用Row来排布

同时这个Row 的children数组太长我们专门用一个方法来产生数组 这样嵌套的层级少就好看

产生星星 我们使用List.generate 这个函数来动态的产生

import "package:flutter/material.dart";

// 这里是用less还是ful呢 如果有状态的话就用fulWidget
class HYStarRating extends StatefulWidget {
  final double rating;     //分数是
  final double maxRating;  //满分是
  final int count;         //准备有几颗星
  final double size;       //star的大小
  final Color unselectedColor; // 未选中时候的颜色
  final Color unselectedColor;   // 选中的时候的颜色
  final Widget unselectedImage;
  final Widget selectedImage;

  HYStarRating({
    @required this.rating,
    this.maxRating = 10,
    this.count = 5,
    this.size = 30,
    this.unselectedColor = const Color(0xffbbbbbb),
    this.selectedColor = const Color(0xffff0000),
    Widget unselectedImage,
    Widget selectedImage
  }): unselectedImage = unselectedImage ?? Icon(Icons.star_border, color: unselectedColor, size: size),
        selectedImage = selectedImage ?? Icon(Icons.star, color: selectedColor, size: size);

  @override
  _HYStarRatingState createState() => _HYStarRatingState();
}

class _HYStarRatingState extends State<HYStarRating> {

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Row(mainAxisSize: MainAxisSize.min, children: buildUnSelectedStar()),
//        100 70 都因该别人个性化的时候用的
        Row(mainAxisSize: MainAxisSize.min, children: buildSelectedStar()),
      ],
    );
  }

  List<Widget> buildUnSelectedStar() {
    return List.generate(widget.count, (index) {
      return widget.unselectedImage;
    });
  }

  List<Widget> buildSelectedStar() {
//    1. 创建stars
    List<Widget> stars= [];
    final star = widget.selectedImage;

//    2. 构建填充的stars
    double oneValue = widget.maxRating / widget.count;
//    向下取整 floor ceil
    int entireCount = (widget.rating / oneValue).floor();
    print(entireCount);
    for(var i = 0 ; i < entireCount; i++ ) {
      stars.add(star);
    }

//    3. 构建部分填充的
//    裁剪Widget
    double leftWidth = ((widget.rating / oneValue) - entireCount) * widget.size;
    final partStar = ClipRect(
      child: star,
      clipper: HYStarClipper(leftWidth),
    );
    stars.add(partStar);
    return stars;
  }
}

// 我们直接自定义一个类 这个类继承字 CustomClipper这个类是管裁剪的
// 这样就可以打出 半个星 或者几点几个星的效果
class HYStarClipper extends CustomClipper<Rect> {
  double width;

  HYStarClipper(this.width);

  @override
  Rect getClip(Size size) {
    // TODO: implement getClip
//   size.height 垂直方向不裁剪
    return Rect.fromLTRB(0, 0, width, size.height);
  }

  @override
  bool shouldReclip(HYStarClipper oldClipper) {
    // TODO: implement shouldReclip
//   要不要重新裁剪 宽度不一致的时候
    return oldClipper.width != this.width;
  }
}

这样就可以使用了

import "package:flutter/material.dart";
import "package:learn_flutter02/douban/widgets/star_rating.dart";

class HYHomeContent extends StatefulWidget {
  @override
  _HYHomeContentState createState() => _HYHomeContentState();
}

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: HYStarRating(rating: 2)
    );
  }
}

在这里插入图片描述

换一个 rating: 3
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的自定义列表块封装示例。以下是一个基本的代码示例: ```dart import 'package:flutter/material.dart'; class CustomListItem extends StatelessWidget { CustomListItem({ this.title, this.subtitle, this.thumbnail, }); final String title; final String subtitle; final Widget thumbnail; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ thumbnail, Expanded( child: Padding( padding: const EdgeInsets.fromLTRB(20.0, 0.0, 2.0, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( title, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 18.0, ), ), const Padding(padding: EdgeInsets.symmetric(vertical: 2.0)), Text( subtitle, style: const TextStyle(fontSize: 16.0), ), ], ), ), ) ], ), ); } } ``` 您可以在需要使用自定义的列表块的地方使用此小部件。例如,以下是一个使用此自定义列表块的示例: ```dart class MyCustomList extends StatelessWidget { @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.all(10.0), children: <Widget>[ CustomListItem( title: 'Flutter', subtitle: 'Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase', thumbnail: Container( decoration: const BoxDecoration(color: Colors.blue), ), ), CustomListItem( title: 'Dart', subtitle: 'A client-optimized language for fast apps on any platform', thumbnail: Container( decoration: const BoxDecoration(color: Colors.green), ), ), CustomListItem( title: 'Material Design', subtitle: 'A design system for building beautiful, natively compiled applications for mobile, web, and desktop', thumbnail: Container( decoration: const BoxDecoration(color: Colors.orange), ), ), ], ); } } ``` 这个示例中,我们使用 `MyCustomList` 小部件来构建一个包含三个自定义列表块的列表。每个列表块都包含一个缩略图、标题和子标题。请注意,我们可以在自定义列表块中使用任何小部件,以便根据自己的需求进行自定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值