重学 Android 自定义 View 系列(八):星星评分控件(RatingBar)
前言
本节实现一个常见的星星评分控件,广泛应用于各种评价类应用中,比如电影评分、商品评价等。难度不大,直接开搂!
最终效果如下:
1. 效果分析
- 显示若干颗星星(默认为5颗,可根据属性配置)。
- 可以通过点击和滑动星星来选择评分。
效果展示:
- 默认显示N颗空星,点击或滑动时,选中的星星将变为填充状态
2. 技术实现
2.1 在 res/values/attrs.xml
文件中,定义属性。两张图片和星星的数量。
<declare-styleable name="RatingBar">
<attr name="starNormal" format="reference"/>
<attr name="starFocus" format="reference"/>
<attr name="gradeNumber" format="integer"/>
</declare-styleable>
2.2 设置控件的尺寸,确定控件大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 高度为一颗星星的高度,加上 padding 的高度
int height = mStarNormalBitmap.getHeight() + getPaddingTop() + getPaddingBottom();
// 宽度为星星数量 * 单颗星星的宽度
int width = mStarNormalBitmap.getWidth() * mGradeNum;
setMeasuredDimension(width, height);
}
2.3 绘制星星,mCurrentGrade
为当前用户选中的等级,用来确定绘制几颗实心星星。
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < mGradeNum; i++) {
if (mCurrentGrade > i) {
// 绘制已选中的实心星星
// drawBitmap 参数: @NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint
canvas.drawBitmap(mStarFocusBitmap, i * mStarNormalBitmap.getWidth(), 0, null);
} else {
// 绘制未选中的空心星星
canvas.drawBitmap(mStarNormalBitmap, i * mStarNormalBitmap.getWidth(), 0, null);
}
}
}
2.4 处理用户交互(重点)
这个控件的关键技术点就是处理触摸手势,这里只使用 MotionEvent.ACTION_DOWN
和 MotionEvent.ACTION_MOVE
,就能应付全部可能手势,不需要抬起动作,注意 最后 return true;
代表消费触摸,如果不为true
,则 MotionEvent.ACTION_MOVE
行为不生效!
下图为安卓控件和屏幕的坐标相关介绍,这里主要使用的是event.getX()
x坐标, 相对于当前控件的,这里先初步认识一下,以后会用到。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
float x = event.getX(); // 获取触摸位置的 x 坐标
float grade = x / mStarNormalBitmap.getWidth() + 1; // 计算当前评分
// 限制评分范围
if (grade < 0) {
grade = 0;
}
if (grade > mGradeNum) {
grade = mGradeNum;
}
// 更新评分并刷新界面
if (mCurrentGrade != (int) grade) {
mCurrentGrade = (int) grade;
invalidate();
Log.i("TAG", "分数:" + mCurrentGrade);
}
break;
default:
break;
}
return true;
}
3. 最后
这里只是绘制星星评分最基础的步骤,比如,还有半颗星的评分,原理一样,感兴趣的可以自行拓展。再会!
源码及更多自定义View已上传Github:DiyView
另外给喜欢记笔记的同学安利一款好用的云笔记软件,对比大部分国内的这个算还不错的,免费好用:wolai