123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- import 'package:flutter/material.dart';
- import 'package:widgets/my_load_image.dart';
- class RatingWidget extends StatefulWidget {
- final int count;
- final double maxRating;
- final double value;
- final double size;
- final double padding;
- final String nomalImage;
- final String selectImage;
- final bool selectAble;
- final ValueChanged<String> onRatingUpdate;
- final bool integerOnly;
- RatingWidget({
- required this.nomalImage,
- required this.selectImage,
- required this.onRatingUpdate,
- this.count = 5,
- this.value = 5.0,
- this.maxRating = 5.0,
- this.size = 20,
- this.padding = 0,
- this.selectAble = false,
- this.integerOnly = false,
- });
- @override
- _RatingWidgetState createState() => _RatingWidgetState();
- }
- class _RatingWidgetState extends State<RatingWidget> {
- late double value;
- @override
- void initState() {
- super.initState();
- value = widget.value;
- }
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTapDown: widget.selectAble ? _handleTap : null,
- onHorizontalDragUpdate: widget.selectAble ? _handleDrag : null,
- child: buildRowRating(),
- );
- }
- void _handleTap(TapDownDetails details) {
- _updateValue(details.localPosition.dx);
- }
- void _handleDrag(DragUpdateDetails details) {
- _updateValue(details.localPosition.dx);
- }
- void _updateValue(double dx) {
- if (dx < 0) dx = 0;
- if (dx >= widget.size * widget.count + widget.padding * (widget.count - 1)) {
- value = widget.maxRating;
- } else {
- for (int i = 1; i <= widget.count; i++) {
- if (dx < i * (widget.size + widget.padding)) {
- value = i * (widget.maxRating / widget.count);
- if (dx < (i - 1) * (widget.size + widget.padding) + widget.size) {
- value -= (widget.size - (dx - (i - 1) * (widget.size + widget.padding))) / widget.size * (widget.maxRating / widget.count);
- }
- break;
- }
- }
- }
- if (widget.integerOnly) {
- value = value.ceilToDouble();
- }
- setState(() {
- widget.onRatingUpdate(value.toStringAsFixed(1));
- });
- }
- int fullStars() {
- return (value / (widget.maxRating / widget.count)).floor();
- }
- double star() {
- if (widget.integerOnly) {
- return 0;
- }
- return (value % (widget.maxRating / widget.count)) / (widget.maxRating / widget.count) * widget.size;
- }
- List<Widget> buildRow() {
- int full = fullStars();
- List<Widget> children = [];
- for (int i = 0; i < full; i++) {
- children.add(MyAssetImage(
- widget.selectImage,
- width: widget.size,
- height: widget.size,
- ));
- if (i < widget.count - 1) {
- children.add(SizedBox(width: widget.padding));
- }
- }
- if (full < widget.count) {
- children.add(
- Stack(
- children: [
- MyAssetImage(
- widget.nomalImage,
- width: widget.size,
- height: widget.size,
- ),
- ClipRect(
- clipper: SMClipper(rating: star()),
- child: MyAssetImage(
- widget.selectImage,
- width: widget.size,
- height: widget.size,
- ),
- ),
- ],
- ),
- );
- }
- return children;
- }
- List<Widget> buildNomalRow() {
- List<Widget> children = [];
- for (int i = 0; i < widget.count; i++) {
- children.add(MyAssetImage(
- widget.nomalImage,
- width: widget.size,
- height: widget.size,
- ));
- if (i < widget.count - 1) {
- children.add(SizedBox(width: widget.padding));
- }
- }
- return children;
- }
- Widget buildRowRating() {
- return Stack(
- children: <Widget>[
- Row(children: buildNomalRow()),
- Row(children: buildRow()),
- ],
- );
- }
- }
- class SMClipper extends CustomClipper<Rect> {
- final double rating;
- SMClipper({required this.rating});
- @override
- Rect getClip(Size size) {
- return Rect.fromLTRB(0.0, 0.0, rating, size.height);
- }
- @override
- bool shouldReclip(SMClipper oldClipper) {
- return rating != oldClipper.rating;
- }
- }
|