android custom star rating control can only display solid stars

Keywords: Android github

Not much, above

Recently, the app needs to make a level display. I look at the UI chart and only show the real stars (lit stars). As shown in the figure below

But most of the online examples of star rating are like this

Show the stars of modesty

By customizing View

package com.starsbar;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class StarBar extends View {
    private int starDistance = 0; //Star spacing
    private int starCount = 5;  //Number of stars
    private int starSize;     //The height and size of stars are generally square, and the width is equal to the height
    private float starMark = 0.0F;   //Rating stars
    private Bitmap starFillBitmap; //Bright star
    private Drawable starEmptyDrawable; //Dark star
    private OnStarChangeListener onStarChangeListener;//Monitor star change interface
    private Paint paint;         //Draw star brush
    private boolean integerMark = false;
    private boolean clickAble = true;

    public StarBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public StarBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    /**
     * Initialize UI components
     */
    private void init(Context context, AttributeSet attrs) {
        setClickable(true);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.StarBar);
        this.starDistance = (int) mTypedArray.getDimension(R.styleable.StarBar_starDistance, 0);
        this.starSize = (int) mTypedArray.getDimension(R.styleable.StarBar_starSize, 20);
        this.starCount = mTypedArray.getInteger(R.styleable.StarBar_starCount, 5);
        this.starEmptyDrawable = mTypedArray.getDrawable(R.styleable.StarBar_starEmpty);
        this.starFillBitmap = drawableToBitmap(mTypedArray.getDrawable(R.styleable.StarBar_starFill));
        mTypedArray.recycle();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(new BitmapShader(starFillBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
    }

    /**
     * Set whether the stars can be changed by clicking and sliding
     */
    public void setClickAble(boolean clickAble) {
        this.clickAble = clickAble;
    }

    /**
     * Set whether integer scoring is required
     *
     * @param integerMark
     */
    public void setIntegerMark(boolean integerMark) {
        this.integerMark = integerMark;
    }

    /**
     * Set the score of the displayed stars
     *
     * @param mark
     */
    public void setStarMark(float mark) {
        if (integerMark) {
            starMark = (int) Math.ceil(mark);
        } else {
            starMark = Math.round(mark * 10) * 1.0f / 10;
        }
        if (this.onStarChangeListener != null) {
            this.onStarChangeListener.onStarChange(starMark);  //Call listening interface
        }
        invalidate();
    }

    /**
     * Get the number of stars displayed
     *
     * @return starMark
     */
    public float getStarMark() {
        return starMark;
    }


    /**
     * Define monitoring interface for Star Click
     */
    public interface OnStarChangeListener {
        void onStarChange(float mark);
    }

    /**
     * Set listening
     *
     * @param onStarChangeListener
     */
    public void setOnStarChangeListener(OnStarChangeListener onStarChangeListener) {
        this.onStarChangeListener = onStarChangeListener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(starSize * starCount + starDistance * (starCount - 1), starSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (starFillBitmap == null || starEmptyDrawable == null) {
            return;
        }
        for (int i = 0; i < starCount; i++) {
            starEmptyDrawable.setBounds((starDistance + starSize) * i, 0, (starDistance + starSize) * i + starSize, starSize);
            starEmptyDrawable.draw(canvas);
        }
        if (starMark > 1) {
            canvas.drawRect(0, 0, starSize, starSize, paint);
            if (starMark - (int) (starMark) == 0) {
                for (int i = 1; i < starMark; i++) {
                    canvas.translate(starDistance + starSize, 0);
                    canvas.drawRect(0, 0, starSize, starSize, paint);
                }
            } else {
                for (int i = 1; i < starMark - 1; i++) {
                    canvas.translate(starDistance + starSize, 0);
                    canvas.drawRect(0, 0, starSize, starSize, paint);
                }
                canvas.translate(starDistance + starSize, 0);
                canvas.drawRect(0, 0, starSize * (Math.round((starMark - (int) (starMark)) * 10) * 1.0f / 10), starSize, paint);
            }
        } else {
            canvas.drawRect(0, 0, starSize * starMark, starSize, paint);
        }
    }


    /**
     * Set the total number of stars
     */
    public void setStarCount(int count){
        starCount = count;
    }
    /**
     * Set the number of bright stars
     */
    public void setRating(int rating){
        if (integerMark) {
            starMark = (int) Math.ceil(rating);
        } else {
            starMark = Math.round(rating * 10) * 1.0f / 10;
        }
        if (this.onStarChangeListener != null) {
            this.onStarChangeListener.onStarChange(starMark);  //Call listening interface
        }
        invalidate();
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (clickAble) {
            int x = (int) event.getX();
            if (x < 0) x = 0;
            if (x > getMeasuredWidth()) x = getMeasuredWidth();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    setStarMark(x * 1.0f / (getMeasuredWidth() * 1.0f / starCount));
                    break;
                }
                case MotionEvent.ACTION_MOVE: {
                    setStarMark(x * 1.0f / (getMeasuredWidth() * 1.0f / starCount));
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    break;
                }
            }
            invalidate();
        }
        return super.onTouchEvent(event);
    }

    /**
     * drawable Transfer to bitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) return null;
        Bitmap bitmap = Bitmap.createBitmap(starSize, starSize, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, starSize, starSize);
        drawable.draw(canvas);
        return bitmap;
    }
}

Solution, in order to display only solid numbers, two methods are added, note:

/**
     * Set the total number of stars
     */
    public void setStarCount(int count){
        starCount = count;
    }
    /**
     * Set the number of bright stars
     */
    public void setRating(int rating){
        if (integerMark) {
            starMark = (int) Math.ceil(rating);
        } else {
            starMark = Math.round(rating * 10) * 1.0f / 10;
        }
        if (this.onStarChangeListener != null) {
            this.onStarChangeListener.onStarChange(starMark);  //Call listening interface
        }
        invalidate();
    }

The above requirements can be realized by using activities together:

 //Non selectable starBar, for display only, not blank
        starBar2=findViewById(R.id.starBar2);
        starBar2.setClickAble(false);
        starBar2.setStarCount(3);
        starBar2.setRating(3);

Another star rating, YStarView

Attach the source download address: https://github.com/soulofandroid/StarsBar
Welcome to download and comment

Posted by tarlejh on Fri, 20 Dec 2019 07:55:15 -0800