重学 Android 自界说 View 系列(八):星星评分控件(RatingBar)

[复制链接]
发表于 2025-12-20 21:11:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
前言

本节实现一个常见的星星评分控件,广泛应用于各种评价类应用中,比如影戏评分、商品评价等。难度不大,直接开搂!
终极结果如下:

1. 结果分析




  • 体现多少颗星星(默以为5颗,可根据属性设置)。
  • 可以通过点击和滑动星星来选择评分。
结果展示:


  • 默认体现N颗空星,点击或滑动时,选中的星星将变为添补状态
2. 技能实现


2.1 在 res/values/attrs.xml 文件中,界说属性。两张图片和星星的数目。

  1.     <declare-styleable name="RatingBar">
  2.         <attr name="starNormal" format="reference"/>
  3.         <attr name="starFocus" format="reference"/>
  4.         <attr name="gradeNumber" format="integer"/>
  5.     </declare-styleable>
复制代码
2.2 设置控件的尺寸,确定控件巨细

  1. @Override
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  3.     super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  4.    
  5.     // 高度为一颗星星的高度,加上 padding 的高度
  6.     int height = mStarNormalBitmap.getHeight() + getPaddingTop() + getPaddingBottom();
  7.     // 宽度为星星数量 * 单颗星星的宽度
  8.     int width = mStarNormalBitmap.getWidth() * mGradeNum;
  9.    
  10.     setMeasuredDimension(width, height);
  11. }
复制代码
2.3 绘制星星,mCurrentGrade 为当前用户选中的品级,用来确定绘制几颗实心星星。

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3.     for (int i = 0; i < mGradeNum; i++) {
  4.         if (mCurrentGrade > i) {
  5.             // 绘制已选中的实心星星
  6.             // drawBitmap 参数: @NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint
  7.             canvas.drawBitmap(mStarFocusBitmap, i * mStarNormalBitmap.getWidth(), 0, null);
  8.         } else {
  9.             // 绘制未选中的空心星星
  10.             canvas.drawBitmap(mStarNormalBitmap, i * mStarNormalBitmap.getWidth(), 0, null);
  11.         }
  12.     }
  13. }
复制代码
2.4 处理处罚用户交互(重点)

这个控件的关键技能点就是处理处罚触摸手势,这里只利用 MotionEvent.ACTION_DOWN 和 MotionEvent.ACTION_MOVE,就能应付全部大概手势,不必要抬起动作,留意 末了 return true; 代表消耗触摸,如果不为true,则 MotionEvent.ACTION_MOVE 举动不收效!
下图为安卓控件和屏幕的坐标干系先容,这里重要利用的是event.getX() x坐标, 相对于当前控件的,这里先开端认识一下,以后会用到。

  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3.     switch (event.getAction()) {
  4.         case MotionEvent.ACTION_DOWN:
  5.         case MotionEvent.ACTION_MOVE:
  6.             float x = event.getX();  // 获取触摸位置的 x 坐标
  7.             float grade = x / mStarNormalBitmap.getWidth() + 1; // 计算当前评分
  8.             // 限制评分范围
  9.             if (grade < 0) {
  10.                 grade = 0;
  11.             }
  12.             if (grade > mGradeNum) {
  13.                 grade = mGradeNum;
  14.             }
  15.             // 更新评分并刷新界面
  16.             if (mCurrentGrade != (int) grade) {
  17.                 mCurrentGrade = (int) grade;
  18.                 invalidate();
  19.                 Log.i("TAG", "分数:" + mCurrentGrade);
  20.             }
  21.             break;
  22.         default:
  23.             break;
  24.     }
  25.     return true;
  26. }
复制代码
3. 末了


这里只是绘制星星评分最根本的步调,比如,尚有半颗星的评分,原理一样,感爱好的可以自行拓展。再见!
源码及更多自界说View已上传Github:DiyView
别的给喜好记条记的同砚安利一款好用的云条记软件,对比大部分国内的这个算还不错的,免费好用:wolai
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表