mo211683 发表于 2021-4-26 23:45

Android评分控件分享

### Android评分控件分享

```
public class TRatingBar extends LinearLayout {
    private boolean mClickable;
    private boolean halfstart;
    private int starCount;
    private int starNum;
    private OnRatingChangeListener onRatingChangeListener;
    private float starImageSize;
    private float starImageWidth;
    private float starImageHeight;
    private float starImagePadding;
    private Drawable starEmptyDrawable;
    private Drawable starFillDrawable;
    private Drawable starHalfDrawable;
    private int y = 1;
    private boolean isEmpty = true;

    public void setStarHalfDrawable(Drawable starHalfDrawable) {
      this.starHalfDrawable = starHalfDrawable;
    }


    public void setOnRatingChangeListener(OnRatingChangeListener onRatingChangeListener) {
      this.onRatingChangeListener = onRatingChangeListener;
    }

    public void setmClickable(boolean clickable) {
      this.mClickable = clickable;
    }

    public void halfStar(boolean halfstart) {
      this.halfstart = halfstart;
    }

    public void setStarFillDrawable(Drawable starFillDrawable) {
      this.starFillDrawable = starFillDrawable;
    }

    public void setStarEmptyDrawable(Drawable starEmptyDrawable) {
      this.starEmptyDrawable = starEmptyDrawable;
    }

    public void setStarImageSize(float starImageSize) {
      this.starImageSize = starImageSize;
    }

    public void setStarImageWidth(float starImageWidth) {
      this.starImageWidth = starImageWidth;
    }

    public void setStarImageHeight(float starImageHeight) {
      this.starImageHeight = starImageHeight;
    }


    public void setStarCount(int starCount) {
      this.starCount = starCount;
    }

    public void setImagePadding(float starImagePadding) {
      this.starImagePadding = starImagePadding;
    }


    public TRatingBar(Context context, AttributeSet attrs) {
      super(context, attrs);
      setOrientation(LinearLayout.HORIZONTAL);
      TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);

      starHalfDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starHalf);
      starEmptyDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starEmpty);
      starFillDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starFill);
      starImageSize = mTypedArray.getDimension(R.styleable.RatingBar_starImageSize, 120);
      starImageWidth = mTypedArray.getDimension(R.styleable.RatingBar_starImageWidth, 60);
      starImageHeight = mTypedArray.getDimension(R.styleable.RatingBar_starImageHeight, 120);
      starImagePadding = mTypedArray.getDimension(R.styleable.RatingBar_starImagePadding, 15);
      starCount = mTypedArray.getInteger(R.styleable.RatingBar_starCount, 5);
      starNum = mTypedArray.getInteger(R.styleable.RatingBar_starNum, 0);
      mClickable = mTypedArray.getBoolean(R.styleable.RatingBar_clickable, true);
      halfstart = mTypedArray.getBoolean(R.styleable.RatingBar_halfstart, false);

      for (int i = 0; i < starNum; ++i) {
            ImageView imageView = getStarImageView(context, false);
            addView(imageView);
      }

      for (int i = 0; i < starCount; ++i) {
            ImageView imageView = getStarImageView(context, isEmpty);
            imageView.setOnClickListener(
                  new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mClickable) {
                              if (halfstart) {
                                    //TODO:This is not the best way to solve half a star,
                                    //TODO:but That's what I can do,Please let me know if you have a better solution
                                    if (y % 2 == 0) {
                                        setStar(indexOfChild(v) + 1f);
                                    } else {
                                        setStar(indexOfChild(v) + 0.5f);
                                    }
                                    if (onRatingChangeListener != null) {
                                        if (y % 2 == 0) {
                                          onRatingChangeListener.onRatingChange(indexOfChild(v) + 1f);
                                          y++;
                                        } else {
                                          onRatingChangeListener.onRatingChange(indexOfChild(v) + 0.5f);
                                          y++;
                                        }
                                    }
                              } else {
                                    setStar(indexOfChild(v) + 1f);
                                    if (onRatingChangeListener != null) {
                                        onRatingChangeListener.onRatingChange(indexOfChild(v) + 1f);
                                    }
                              }

                            }

                        }
                  }
            );
            addView(imageView);
      }
    }


    private ImageView getStarImageView(Context context, boolean isEmpty) {
      ImageView imageView = new ImageView(context);
      ViewGroup.LayoutParams para = new ViewGroup.LayoutParams(
                Math.round(starImageWidth),
                Math.round(starImageHeight)
      );
      imageView.setLayoutParams(para);
      imageView.setPadding(0, 0, Math.round(starImagePadding), 0);
      if (isEmpty) {
            imageView.setImageDrawable(starEmptyDrawable);
      } else {
            imageView.setImageDrawable(starFillDrawable);
      }
      return imageView;
    }

    public void setStar(float starCount) {

      int fint = (int) starCount;
      BigDecimal b1 = new BigDecimal(Float.toString(starCount));
      BigDecimal b2 = new BigDecimal(Integer.toString(fint));
      float fPoint = b1.subtract(b2).floatValue();


      starCount = fint > this.starCount ? this.starCount : fint;
      starCount = starCount < 0 ? 0 : starCount;

      //drawfullstar
      for (int i = 0; i < starCount; ++i) {
            ((ImageView) getChildAt(i)).setImageDrawable(starFillDrawable);
      }

      //drawhalfstar
      if (fPoint > 0) {
            ((ImageView) getChildAt(fint)).setImageDrawable(starHalfDrawable);

            //drawemptystar
            for (int i = this.starCount - 1; i >= starCount + 1; --i) {
                ((ImageView) getChildAt(i)).setImageDrawable(starEmptyDrawable);
            }

      } else {
            //drawemptystar
            for (int i = this.starCount - 1; i >= starCount; --i) {
                ((ImageView) getChildAt(i)).setImageDrawable(starEmptyDrawable);
            }

      }

    }

    /**
   * change start listener
   */
    public interface OnRatingChangeListener {

      void onRatingChange(float RatingCount);

    }

}


```

第二步:
在values中,的attrs文件中,增加自定义属性,如果没有这个文件,自己创建一个。
```
<declare-styleable name="RatingBar" tools:ignore="ResourceName">
      <attr name="starImageSize" format="dimension" />
      <attr name="starImageWidth" format="dimension" />
      <attr name="starImageHeight" format="dimension" />
      <attr name="starImagePadding" format="dimension" />
      <attr name="starCount" format="integer" />
      <attr name="starNum" format="integer" />
      <attr name="starEmpty" format="reference" />
      <attr name="starFill" format="reference" />
      <attr name="starHalf" format="reference" />
      <attr name="clickable" format="boolean" />
      <attr name="halfstart" format="boolean" />
    </declare-styleable>
```

使用:
```

      <xxxx.TRatingBar
               
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:halfstart="false"
                app:starCount="5"
                app:starImageHeight="50dp"
                app:starImageWidth="50dp"
                app:starImagePadding="20dp"
                app:starEmpty="ic_nor" 放自己的切图
                app:starFill="ic_full"放自己的切图
                />
```

kbqns2012 发表于 2021-4-27 07:07

mark一下,谢谢分享

richens 发表于 2021-4-27 07:12

收藏学习,谢谢分享!

逝去的初夏 发表于 2021-4-27 07:37

Android有一个AppCompatRatingBar呢,也是评分用的

江南云 发表于 2021-4-27 07:53

评分控件看起来比较好用,谢谢分享!
页: [1]
查看完整版本: Android评分控件分享