SoFunction
Updated on 2025-04-09

Android Custom Star Review Space Sample Code

I have nothing to do and write a star review control using a custom view. Although there are many of this controls on the Internet, I wrote them myself, so I will record them here.

First, custom properties are required

<declare-styleable name="Rate">
    <!--The attributes are:Single width,high,Distance between,Number of activated,Total quantity,Activateddrawable,没有Activateddrawable,Is it possible to select quantity-->
    <attr name="custom_rate_width" format="dimension"/>
    <attr name="custom_rate_height" format="dimension"/>
    <attr name="custom_rate_padding" format="dimension"/>
    <attr name="custom_rate_active_size" format="integer"/>
    <attr name="custom_rate_size" format="integer"/>
    <attr name="custom_rate_active_drawable" format="reference"/>
    <attr name="custom_rate_disactive_drawable" format="reference"/>
    <attr name="custom_rate_touch" format="boolean"/>
  </declare-styleable>

Initialization code

 protected void init(Context context, AttributeSet attrs) {
    TypedArray array = (attrs, );
    int activeId = 0;
    int disactiveId = 0;
    if (array != null) {
      size = (.Rate_custom_rate_size, 5);
      activeSize = (.Rate_custom_rate_active_size, 3);
      rateWidth = (.Rate_custom_rate_width, 0);
      rateHeight = (.Rate_custom_rate_height, 0);
      activeId = (.Rate_custom_rate_active_drawable, 0);
      disactiveId = (.Rate_custom_rate_disactive_drawable, 0);
      padding = (.Rate_custom_rate_padding, 0);
      isTouch = (.Rate_custom_rate_touch, false);
      ();
    }
    // If there is no width and height, set a default value    if (rateHeight <= 0){
      rateHeight = 80;
    }
    if (rateWidth <= 0){
      rateWidth = 80;
    }
    if (activeId!=0){
      activeBitmap = (getResources(), activeId);
      //If the width and height are not set      if (rateWidth <= 0) {
        rateWidth = ();
      }
      //Compress the image to the set width and height      activeBitmap = (activeBitmap, (int) rateWidth, (int) rateHeight, false);
    }
    if (disactiveId != 0){
      disactiveBitmap = (getResources(), disactiveId);
      if (rateHeight <= 0) {
        rateHeight = ();
      }
      disactiveBitmap = (disactiveBitmap, (int) rateWidth, (int) rateHeight, false);
    }
    mPaint = new Paint();//Initialize the bitmap brush    (true);
    activPaint = new Paint();//Initialize the selected star brush    (true);
    ();
    disactivPaint = new Paint();//Initialize the brush with unselected stars    (true);
    ();
  }

The onMeasure method sets the width and height of the view. If the width and height of each star control are greater than the width and height of the actual view, the width and height of the star space are used to make the width and height of the view.

@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = (widthMeasureSpec);
    int widthSize = (widthMeasureSpec);
    int heightMode = (heightMeasureSpec);
    int heightSize = (heightMeasureSpec);
    // Calculate width    if (widthMode == ) {
      //If the width of the view is smaller than the width of the set size* star, use size * (int) (padding + rateWidth) as the width of the control.      if (widthSize < size * (int) (padding + rateWidth)) {
        width = size * (int) (padding + rateWidth);
      } else {
        width = widthSize;
      }
    } else {
      width = size * (int) (padding + rateWidth)-padding;
    }
    // Calculate high    if (heightMode == ) {
      //If the height of the view is smaller than the height of the set star, use the height of the star as the height of the control      if (heightSize < rateHeight) {
        height = (int) rateHeight + 5;
      } else {
        height = heightSize;
      }
    } else {
      height = (int) rateHeight + 5;
    }
    setMeasuredDimension(width, height);
  }

Draw in onDraw method

//Start draw active    for (int i = 0; i < activeSize; i++) {
      if (activeBitmap != null){
        if (i == 0) {
          (activeBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint);
        } else {
          (activeBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint);
        }
      }else {
        drawActivRate(i,canvas);
      }
    }
// // Start drawing disactive    for (int i = activeSize; i < size; i++) {
      if (disactiveBitmap != null){
        if (i == 0) {
          (disactiveBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint);
        } else {
          (disactiveBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint);
        }
      }else {
        drawDisActivRate(i,canvas);
      }
    }

The above two methods drawActivRate and drawDisActivRate are used, which are the default stars drawn in and out of activity when there is no picture of the stars in the activity and the stars in the activity:

/**
    * Drawing yellow five-pointed stars (in active)
    * */
  private void drawActivRate(int position,Canvas canvas){
    float radius = rateWidth/2;//Draw the garden according to the position of each star and determine the location of the five points of the five-point star    float angle = 360/5;
    float centerX = (rateWidth+padding)*(position+1)-padding-radius;//Get the X coordinate in the center of each star space    float centerY =height/2;//Get the y coordinate in the center of each star space    Path mPath = new Path();
    (centerX,centerY-radius);
    (centerX+(float) ((angle*2-90)* / 180)*radius,centerY+(float)((angle*2-90)* / 180)*radius);
    ( centerX-(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius);
    ( centerX+(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius);
    ( centerX-(float)((angle*3-180)* / 180)*radius,centerY+(float)((angle*3-180)* / 180)*radius);
//    (centerX,centerY-radius);
    ();
    (mPath,activPaint);
  }
  /**
    * Drawing gray five-pointed stars
    * */
  private void drawDisActivRate(int position,Canvas canvas){
    float radius = rateWidth/2;
    float angle = 360/5;
    float centerX = (rateWidth+padding)*(position+1)-padding-radius;
    float centerY =height/2;
    Path mPath = new Path();
    (centerX,centerY-radius);
    (centerX+(float) ((angle*2-90)* / 180)*radius,centerY+(float)((angle*2-90)* / 180)*radius);
    ( centerX-(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius);
    ( centerX+(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius);
    ( centerX-(float)((angle*3-180)* / 180)*radius,centerY+(float)((angle*3-180)* / 180)*radius);
//    (centerX,centerY-radius);
    ();
    (mPath,disactivPaint);
  }

Finally, the processing of selected and unselected stars is handled in the onTouchEvent method.

@Override
  public boolean onTouchEvent(MotionEvent event) {
    if (!isTouch){//If touch is not supported      return false;
    }
    switch (()) {
      case MotionEvent.ACTION_DOWN:
        touchX = ();
        touchY = ();
        for (int i = 0; i < size; i++) {
          if (i == 0) {
            if (0.0 < touchX && touchX < rateWidth+padding/2) {
              activeSize = 1;
            }
          }else {
            if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){
              activeSize = i+1;
            }
          }
        }
        invalidate();
        break;
      case MotionEvent.ACTION_UP:
        if ( null!= changeListener){
          (activeSize);
        }
        break;
      case MotionEvent.ACTION_MOVE:
        touchX = ();
        touchY = ();
        for (int i = 0; i < size; i++) {
          if (i == 0) {
            if (0.0 < touchX && touchX < rateWidth+padding/2) {
              activeSize = 1;
            }
          }else {
            if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){
              activeSize = i+1;
            }
          }
        }
        invalidate();
        if (touchX<=0){
          activeSize = 0;
        }
        break;
    }
    return true;
  }

The above is the star comment control written by the custom view. The annotations in the code are already detailed, so I won’t say more.

Source code address

The above is the example code of Android custom star comment space introduced to you by the editor. I hope it will be helpful to everyone!