【实际效果图】
1.相关资源:
/** * 自定义View的几个重要方法步骤: * 1、构造方法 创建 对象:据使用的那种方式调用那种方法 * 2、获取View的大小 :onMeasure(int,int) * 3、确定View的位置,view自身有一定的权力,但是决定权在父布局上 : onLayout(); * 4、绘制View的内容:onDraw(Canvas) *///自定义控件---星级评分条(只用于显示,不可拖动)public class MyRatingBar extends View { private Paint paint;//画笔 private float rateNum;//当前星级值(0~5) private int stepSizeType;//步长类型 private Bitmap starYesBitmap;//满星图片 private Bitmap starNoBitmap;//无星图片 private Bitmap starHalfBitmap;//半星图片 //此处的final整数值应该与attr里面的属性枚举值保持一致 public final static int halfStar = 0;//有半星 public final static int fullStar = 1;//无半星 /** * 在布局文件中使用自定义的view时,调用此构造方法 */ public MyRatingBar(Context context, AttributeSet attrs) { super(context, attrs); //获取自定义属性 TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.MyRatingBar);//获取属性命名空间 rateNum = typeArray.getFloat(R.styleable.MyRatingBar_rateNum, 0);//获取属性值-星级值 stepSizeType = typeArray.getInt(R.styleable.MyRatingBar_stepSizeType, 0);//获取属性值-步长类型 int starYesID = typeArray.getResourceId(R.styleable.MyRatingBar_star_yes, R.drawable.star_yes); int starNoID = typeArray.getResourceId(R.styleable.MyRatingBar_star_no, R.drawable.star_no); int starHalfID = typeArray.getResourceId(R.styleable.MyRatingBar_star_half, R.drawable.star_half); starYesBitmap = BitmapFactory.decodeResource(getResources(), starYesID); starNoBitmap = BitmapFactory.decodeResource(getResources(), starNoID); starHalfBitmap = BitmapFactory.decodeResource(getResources(), starHalfID); initView(); } /** * 初始化视图数据 */ private void initView() { paint = new Paint(); paint.setAntiAlias(true);//设置抗锯齿 //自定义属性若想属性生效,必须刷新状态 flushState(); } /** * 测量View的大小 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(starNoBitmap.getWidth() * 5, starNoBitmap.getHeight() * 1); } /** * 确定View的位置 */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { //自定义view的时候,一般来说作用不大,故此处不做任何处理 super.onLayout(changed, left, top, right, bottom); } /** * 绘制View的内容 */ @Override protected void onDraw(Canvas canvas) { int starWidth = starNoBitmap.getWidth(); //无半星 if (stepSizeType == 1) { int index = (int) (rateNum / 1); for (int i = 0; i < 5; i++) { if (i < index) { canvas.drawBitmap(starYesBitmap, starWidth * i, 0, paint);//设置第i颗星为满星 } else { canvas.drawBitmap(starNoBitmap, starWidth * i, 0, paint);//设置第i颗星为无星 } } } //有半星 else if (stepSizeType == 0) { int index = (int) (rateNum / 0.5); for (int i = 0; i < 5; i++) { if (i * 2 < index) { if (i * 2 <= (index - 2)) { canvas.drawBitmap(starYesBitmap, starWidth * i, 0, paint);//设置第i颗星为满星 } else { canvas.drawBitmap(starHalfBitmap, starWidth * i, 0, paint);//设置第i颗星为半星 } } else { canvas.drawBitmap(starNoBitmap, starWidth * i, 0, paint);//设置第i颗星为无星 } } } } /** * 监听手势事件 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } /** * 刷新View的状态 */ private void flushState() { //刷新View,因本例子比较简单,所以flushState()没啥用,只是跳到了flushView()而已,不过复杂点的控件的话,还是将刷新状态和刷新视图分开比较好 flushView(); } /** * 刷新View的内容 */ private void flushView() { //刷新界面,会重新调用onDraw()方法,不在UI线程中刷新界面得使用postInvalidate(). invalidate(); } public void setRateNum(float rateNum) { this.rateNum = rateNum; flushState(); } public void setStepSizeType(int stepSizeType) { this.stepSizeType = stepSizeType; flushState(); } public void setStarYesBitmap(Bitmap starYesBitmap) { this.starYesBitmap = starYesBitmap; flushState(); } public void setStarNoBitmap(Bitmap starNoBitmap) { this.starNoBitmap = starNoBitmap; flushState(); } public void setStarHalfBitmap(Bitmap starHalfBitmap) { this.starHalfBitmap = starHalfBitmap; flushState(); }}
自定义属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyRatingBar"> <attr name="rateNum" format="float"/> <attr name="stepSizeType" > <enum name="halfStar" value="0" /> <enum name="fullStar" value="1" /> </attr> <attr name="star_yes" format="reference"/> <attr name="star_no" format="reference"/> <attr name="star_half" format="reference"/> </declare-styleable> </resources>
图片资源
2.使用说明:
属性说明:
在XML中设置属性:
在Java中设置属性:
时间: 2025-01-13 11:31:07