Android自定义RatingBar,评分控件

来源:互联网 发布:linux yum安装php环境 编辑:程序博客网 时间:2024/05/12 03:07

前言

之前有使用系统的RatingBar,发现不太灵活
于是自己写一个

实现效果

效果

原理

原理图
这里写图片描述
首先得有两张评星的图,找ui妹子切一下
为了方便定制,我这里写死了宽高 即整个控件的高度就是星星的高度
整体控件宽高按照需求写死
我们还需要几个自定义属性,才能将整个RatingBar绘制出来
padding值 即每个星星之间的距离,我这里五颗星星是居中排版
所以在设置参数时还是需要小小的计算的

每个星星之间的padding值
星星的总颗数
点亮的星星的颗数
点亮星星的样式
默认未点亮星星的样式

res/values/attrs

<?xml version="1.0" encoding="utf-8"?><resources>    <!--评星-->    <declare-styleable name="StarIndicator" >        <attr name="indicator_icon_chose" format="reference"/>        <attr name="indicator_icon_normal" format="reference"/>        <attr name="indicator_margin_left" format="dimension" />        <attr name="indicator_star_size" format="integer" />        <attr name="indicator_star_chose" format="integer"/>    </declare-styleable></resources>

这里的margin_left 就是上面的星星之间的距离padding

主程序代码

xml

    <com.chonghao.evaluatestardemo.widget.StarIndicator        android:id="@+id/star"        android:layout_width="200dp"  //写死整个View宽度        android:layout_height="28dp"  //写死整个View高度,也是星星高度        android:layout_gravity="center_vertical"          app:indicator_icon_chose="@mipmap/home_star_pre" //选中星星图片        app:indicator_icon_normal="@mipmap/home_star_nor" //未选中星星图片        app:indicator_margin_left="10dp"  //星星间距        app:indicator_star_chose="5"  //选中星星个数        app:indicator_star_size="5"/>  //星星总个数

自定义View StarIndicator

package com.chonghao.evaluatestardemo.widget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.drawable.BitmapDrawable;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.chonghao.evaluatestardemo.R;import java.util.ArrayList;import java.util.List;/** * Created by ccb on 2017/8/29. * 评分指示器 自定义控件 */public class StarIndicator extends View {    /**     * 选择的星星 的bitmap     */    private Bitmap drawable_chose;    /**     * 非选择的星星 的bitmap     */    private Bitmap drawable_normal;    /**     * 星星总颗数 的bitmap     */    private int mStarNumber;    /**     * 选择的星星颗数 的bitmap     */    private int mChoseNumber;    /**     * 邻近星星之间的padding值     */    private float mPaddingLeft;    /**     * 整个View的高度     */    private int mHeight;    /**     * 整个View的宽度     */    private int mWidth;    /**     * 画笔     */    private Paint mPaint;    /**     * 最左侧星星距离左边界的距离     */    private float mLeft0;    /**     * 每个星星定位点 点集合     */    private List<RectF> mPointList;    /**     * 星星点击事件回调     */    private StarChoseListener mStarChoseListener;    public void setStarChoseListener(StarChoseListener starChoseListener) {        mStarChoseListener = starChoseListener;    }    public interface StarChoseListener {        void choseNumber(int num);    }    public StarIndicator(Context context) {        this(context, null);    }    public StarIndicator(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public StarIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StarIndicator, defStyleAttr, 0);        //获取选中图片        BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(R.styleable.StarIndicator_indicator_icon_chose);        drawable_chose = drawable.getBitmap();        //获取选中图片        BitmapDrawable drawable1 = (BitmapDrawable) a.getDrawable(R.styleable.StarIndicator_indicator_icon_normal);        drawable_normal = drawable1.getBitmap();        //获取star个数        mStarNumber = a.getInteger(R.styleable.StarIndicator_indicator_star_size, 5);        //选中个数        mChoseNumber = a.getInteger(R.styleable.StarIndicator_indicator_star_chose, 5);        //获取 间隙        mPaddingLeft = a.getDimension(R.styleable.StarIndicator_indicator_margin_left, 5);        //回收        a.recycle();        initPaint();        Log.d("tag",                mStarNumber + "mStarNumber" +                        mChoseNumber + "mChoseNumber" +                        mPaddingLeft + "mPaddingLeft" +                        drawable_chose + "drawable_chose" +                        drawable_normal + "drawable_normal"        );    }    private void initPaint() {        //获取xml中的属性        //初始化paint,初始化一些其他内容        mPaint = new Paint();        mPaint.setAntiAlias(true);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mHeight = getMeasuredHeight();        mWidth = getMeasuredWidth();        Log.d("tag", "mHeight" + mHeight                + "mWidth" + mWidth        );        //测量控件宽高        //计算文字宽高        mLeft0 = (mWidth - mStarNumber * mHeight - mPaddingLeft * (mStarNumber - 1)) * 0.5f;        mPointList = new ArrayList<>();        for (int i = 0; i < mStarNumber; i++) {            float left = mLeft0 + i * (mPaddingLeft + mHeight);            mPointList.add(new RectF(left, 0, left + mHeight, mHeight));        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //画icon        for (int i = 0; i < mPointList.size(); i++) {            if (i < mChoseNumber) {                canvas.drawBitmap(drawable_chose, null, mPointList.get(i), mPaint);            } else {                canvas.drawBitmap(drawable_normal, null, mPointList.get(i), mPaint);            }        }    }    public void setChoseNumber(int choseNumber) {        mChoseNumber = choseNumber;        postInvalidate();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                break;            case MotionEvent.ACTION_MOVE:            case MotionEvent.ACTION_UP:                float x = event.getX();                if (x > mWidth) {                    x = mWidth;                }                if (x < 0) {                    x = 0;                }                int a;                if (x <= mLeft0) {//最左侧                    setChoseNumber(a = 0);                } else if (x >= (mWidth - mLeft0)) {//最右侧  有多少颗 亮多少颗                    a = mStarNumber;                    setChoseNumber(mStarNumber);                } else {                     a = (int) ((x - mLeft0) / (mHeight + mPaddingLeft) + 1);                    setChoseNumber(a);                }                if (mStarChoseListener != null) {                    mStarChoseListener.choseNumber(a);                }                break;        }        return true;    }}

MainActivity

      StarIndicator star = (StarIndicator) findViewById(R.id.star);        star.setChoseNumber(3); //设置选中个数        //设置监听        star.setStarChoseListener(new StarIndicator.StarChoseListener() {            @Override            public void choseNumber(int num) {                showToast(num + "");            }        });

好了 做起来还是很简单的!

原创粉丝点击