Android自定义星星控件,精确到float显示

http://blog.csdn.net/a756213932/article/details/51939422

这个老哥给了我思路

但是他竟然用了BitmapShader,我觉得是完全没有必要的,drawBitmap(..rect1,rect2..)这个api已经为我们处理好缩放了

还有这个老哥精确到0.1,我这里精确到float

我这里没有弄竖排的,因为项目只有横排的需求,不愿浪费这个时间去完善

这里没有弄拖拽滑动改变星级的,因为也没有这个需求,而且滑动的起始点我一时里感觉都不合适,也没弄


效果展示



支持的所有属性

<declare-styleable name="StarGroupView">
    <attr format="dimension" name="star_size"/>
    <attr format="dimension" name="star_padding"/>
    <attr format="dimension" name="padding_left"/>
    <attr format="dimension" name="padding_top"/>
    <attr format="dimension" name="padding_right"/>
    <attr format="dimension" name="padding_bottom"/>
    <attr format="integer" name="star_count"/>
    <!--star_score代表一共有多少分-->
    <attr format="float" name="star_score"/>
    <attr format="reference" name="star_empty_drawable"/>
    <attr format="reference" name="star_fill_drawable"/>
</declare-styleable>

也可以在代码里动态设置多少分

StarGroupView starGroupView = findViewById(R.id.star_group_view);
starGroupView.setScore(7.7f);


xml使用

<com.example.demo.StarGroupView
    android:id="@+id/star_group_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    StarGroupView:star_count="9"
    StarGroupView:star_empty_drawable="@drawable/star_empty"
    StarGroupView:star_fill_drawable="@drawable/star_full"
    StarGroupView:star_size="9dp"
    StarGroupView:star_score="5.7"/>


全部代码(因为做了一些优化,所以晦涩难懂,推荐看上面链接里的文章)

public class StarGroupView extends View {
    public StarGroupView(Context context) {
        super(context);
    }

    public StarGroupView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public StarGroupView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private int starCounts;
    private float score;
    private int starWidth;
    private int starHeight;
    private int starPadding;
    private int paddingLeft;
    private int paddingTop ;
    private int paddingRight ;
    private int paddingBottom;

    private Bitmap starEmptyBitmap;
    private Bitmap starFullBitmap;
    private int starBitmapWidth;
    private int startBitmapHeight;
    private Paint paint;

    private Rect rect1;//两个复用的rect
    private Rect rect2;

    //默认属性
    private void init(Context context, AttributeSet attrs) {
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.StarGroupView);
        starPadding = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_padding, 0);
        paddingLeft = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_left, 0);
        paddingTop = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_top, 0);
        paddingRight = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_right, 0);
        paddingBottom = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_bottom, 0);
        starWidth = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_size, 20);
        starHeight = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_size, 20);
        starCounts = mTypedArray.getInteger(R.styleable.StarGroupView_star_count, 5);
        score = mTypedArray.getFloat(R.styleable.StarGroupView_star_score, 3.6f);
        Drawable starEmptyDrawable = mTypedArray.getDrawable(R.styleable.StarGroupView_star_empty_drawable);
        Drawable starFullDrawable = mTypedArray.getDrawable(R.styleable.StarGroupView_star_fill_drawable);
        mTypedArray.recycle();

        starWidth = DensityUtils.dp2px(context, starWidth);
        starHeight = DensityUtils.dp2px(context, starHeight);
        starPadding = DensityUtils.dp2px(context, starPadding);
        paddingLeft = DensityUtils.dp2px(context, paddingLeft);
        paddingTop = DensityUtils.dp2px(context, paddingTop);
        paddingRight = DensityUtils.dp2px(context, paddingRight);
        paddingBottom = DensityUtils.dp2px(context, paddingBottom);

        starEmptyBitmap = (starEmptyDrawable) != null ? ((BitmapDrawable) starEmptyDrawable).getBitmap() : null;
        starFullBitmap = (starFullDrawable) != null ? ((BitmapDrawable) starFullDrawable).getBitmap() : null;

        starBitmapWidth = starEmptyBitmap != null ? starEmptyBitmap.getWidth() : 0;
        startBitmapHeight = starEmptyBitmap != null ? starEmptyBitmap.getHeight() : 0;

        paint = new Paint();

        rect1 = new Rect();
        rect2 = new Rect();
    }

    public void setScore(float score) {
        this.score = score;
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthSpecMode == MeasureSpec.AT_MOST) {
            widthSpecSize = starWidth * starCounts + starPadding * (starCounts - 1) + paddingLeft + paddingRight;
        }

        if (heightSpecMode == MeasureSpec.AT_MOST) {
            heightSpecSize = starHeight + paddingTop + paddingBottom;
        }

        setMeasuredDimension(widthSpecSize, heightSpecSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //计算填充的star
        int score = (int) this.score;
        if (score > this.score) {
            score--;
        }
        //画整数个被填充的star
        int startX = - starWidth - starPadding + paddingLeft;//所有的星星的起点都放在这里
        for (int i = 0; i < score; i ++) {
            startX += starWidth + starPadding;
            rect1.left = startX;
            rect1.top = paddingTop;
            rect1.right = startX + starWidth;
            rect1.bottom = starHeight + paddingTop;
            canvas.drawBitmap(
                    starFullBitmap,
                    null,
                    rect1,
                    paint);
            //new Rect(startX, 0, startX + starWidth, starHeight),
        }
        //画填充的star和部分未填充的star
        float fillRate = this.score - score;
        startX += starWidth + starPadding;
        rect1.left = 0;
        rect1.top = 0;
        rect1.right = (int) (starBitmapWidth * fillRate);
        rect1.bottom = startBitmapHeight;
        rect2.left = startX;
        rect2.top = paddingTop;
        rect2.right = (int) (startX + fillRate * starWidth);
        rect2.bottom = starHeight + paddingTop;
        canvas.drawBitmap(
                starFullBitmap,
                rect1,
                rect2,
                paint);
        rect1.left = (int) (starBitmapWidth * fillRate);
        rect1.top = 0;
        rect1.right = starBitmapWidth;
        rect1.bottom = startBitmapHeight;
        rect2.left = (int) (startX + fillRate * starWidth);
        rect2.top = paddingTop;
        rect2.right = startX + starWidth;
        rect2.bottom = starHeight + paddingTop;
        canvas.drawBitmap(
                starEmptyBitmap,
                rect1,
                rect2,
                paint);
        //画整数个未被填充的star
        if (score + 1 != starCounts) {
            for (int i = score + 1; i < starCounts; i ++) {
                startX += starWidth + starPadding;
                rect1.left = startX;
                rect1.top = paddingTop;
                rect1.right = startX + starWidth;
                rect1.bottom = starHeight + paddingTop;
                canvas.drawBitmap(
                        starEmptyBitmap,
                        null,
                        rect1,
                        paint);
            }
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值