首先看下效果图
星星是两个不同的图片
首先老套路:自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RatingBar">
<attr name="starNormal" format="reference"/>
<attr name="starFocus" format="reference"/>
<attr name="gradeNumber" format="integer"/>
</declare-styleable>
</resources>
自定义RatingBar,绘制两张图片,根据getX的位置绘制不同的图片,比较简单直接贴源码
public class RatingBar extends View {
private Bitmap mStarNormalBitmap, mStarFocusBitmap;
private int mGradeNumber = 5;
private int mCurrentGrade = 0;
public RatingBar(Context context) {
this(context, null);
}
public RatingBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);
int starNormalId = ta.getResourceId(R.styleable.RatingBar_starNormal, 0);
if (starNormalId == 0) {
throw new RuntimeException("请设置属性 starNormal ");
}
mStarNormalBitmap = BitmapFactory.decodeResource(getResources(), starNormalId);
int starFocusId = ta.getResourceId(R.styleable.RatingBar_starFocus, 0);
if (starFocusId == 0) {
throw new RuntimeException("请设置属性 starFocus ");
}
mStarFocusBitmap = BitmapFactory.decodeResource(getResources(), starFocusId);
mGradeNumber = ta.getInt(R.styleable.RatingBar_gradeNumber, mGradeNumber);
ta.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = mStarFocusBitmap.getHeight();
int width = (mStarFocusBitmap.getWidth()+getPaddingLeft()) * mGradeNumber;
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < mGradeNumber; i++) {
int x = i * (mStarFocusBitmap.getWidth()+getPaddingLeft());
if(mCurrentGrade>i) {
canvas.drawBitmap(mStarFocusBitmap, x, 0, null);
}else{
canvas.drawBitmap(mStarNormalBitmap, x, 0, null);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
//case MotionEvent.ACTION_DOWN:// 按下 尽量减少onDraw()的调用
case MotionEvent.ACTION_MOVE:
//case MotionEvent.ACTION_UP:// 抬起 尽量减少onDraw()的调用
float x = event.getX();
//获取当前的评分
int currentGrade= (int) (moveX/(mStarFocusBitmap.getWidth()+getPaddingLeft())+1);//当前评分
if (currentGrade < 0) {
currentGrade = 0;
}
if (currentGrade > mGradeNumber) {
currentGrade = mGradeNumber;
}
if (currentGrade == mCurrentGrade) {
return true;//消费当前事件。减少invalidate
}
// 再去刷新显示
mCurrentGrade = currentGrade;
invalidate();
break;
}
return true;//消费当前事件
}
}
布局使用
<com.peakmain.view.ratingbar.RatingBar
app:gradeNumber="5"
app:starNormal="@drawable/star_normal"
app:starFocus="@drawable/star_selected"
android:layout_width="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:layout_height="wrap_content" />
网友评论