smoothratingbar icon indicating copy to clipboard operation
smoothratingbar copied to clipboard

Does not change state

Open Sameerkash opened this issue 4 years ago • 7 comments

I'm using this package to show the stars of a particular review in my app, I noticed that after I update the state with ChnageNotifer and update the values, the stars don't change state. I have to hot restart my app for new changes to be reflected.

Sameerkash avatar May 24 '20 12:05 Sameerkash

can you show me snippets of your code ?

thangmam avatar May 26 '20 07:05 thangmam

can you show me snippets of your code?

I had to refactor my code to meet deadlines, I will surely reproduce it and show it to you soon.

Sameerkash avatar May 28 '20 14:05 Sameerkash

I can confirm this problem, I have readOnly page where user cannot change stars, then I have edit page, when I edit it, come back and use refreshIndicator, the new value is applied but stars are not filled. Only if I scroll all the way to the bottom, stars are redrawn.

marhyno avatar Jul 11 '20 19:07 marhyno

I have a same error sir. After i loaded data from server, i was setState(() { isReadOnly = false; star = 3.5; }); but SmoothStarRating not update star = 3.5, it still 0 star. Plz help me found issue, i tried it many times but not success. Looking forward to hearing from you soon.

vientn1998 avatar Jul 20 '20 00:07 vientn1998

Issue mentioned by @marhyno occurs for us too on the version 1.1.1. The scenario is that after updating starCount and rating to a higher value then when initialised, the rating value remains the same and the stars are not filled (just outlined). It could be the fact the currentRating from _SmoothStarRatingState is initialised only in initState() and does not change value when calling setState().

Any timeline when this could be fixed?

CameliaTripon avatar Sep 21 '20 12:09 CameliaTripon

I don't have time to push a PR, but here is a stateless widget that you can use to show just stars and will update on each rebuild

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class StaticSmoothStarRating extends StatelessWidget {
  final int starCount;
  final double rating;
  final Color color;
  final Color borderColor;
  final double size;
  final bool allowHalfRating;
  final IconData filledIconData;
  final IconData halfFilledIconData;
  final IconData defaultIconData; //this is needed only when having fullRatedIconData && halfRatedIconData
  final double spacing;
  final double halfStarThreshold = 0.53; //half star value starts from this number

  const StaticSmoothStarRating({
    Key key,
    this.starCount = 5,
    this.spacing = 0.0,
    this.rating = 0.0,
    this.defaultIconData = Icons.star_border,
    this.color,
    this.borderColor,
    this.size = 25,
    this.filledIconData = Icons.star,
    this.halfFilledIconData = Icons.star_half,
    this.allowHalfRating = true,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: Wrap(
          alignment: WrapAlignment.start,
          spacing: spacing,
          children: List.generate(starCount, (index) => buildStar(context, index))),
    );
  }

  Widget buildStar(BuildContext context, int index) {
    double currentRating = normalizeRating(rating);
    Icon icon;
    if (index >= currentRating) {
      icon = Icon(
        defaultIconData,
        color: borderColor ?? Theme.of(context).primaryColor,
        size: size,
      );
    } else if (index > currentRating - (allowHalfRating ? halfStarThreshold : 1.0) && index < currentRating) {
      icon = Icon(
        halfFilledIconData,
        color: color ?? Theme.of(context).primaryColor,
        size: size,
      );
    } else {
      icon = Icon(
        filledIconData,
        color: color ?? Theme.of(context).primaryColor,
        size: size,
      );
    }
    return icon;
  }

  double normalizeRating(double newRating) {
    var k = newRating - newRating.floor();
    if (k != 0) {
      //half stars
      if (k >= halfStarThreshold) {
        newRating = newRating.floor() + 1.0;
      } else {
        newRating = newRating.floor() + 0.5;
      }
    }
    return newRating;
  }
}

2math avatar Nov 27 '20 09:11 2math

worked! thank you.

takax2021 avatar Apr 27 '21 11:04 takax2021