当前位置: 首页 > article >正文

重学 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_DOWNMotionEvent.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


http://www.kler.cn/a/414282.html

相关文章:

  • macOS 桌面悬浮窗口
  • Blender 运行python脚本
  • 乐鑫发布 esp-iot-solution v2.0 版本
  • 【工具】JS解析XML并且转为json对象
  • Android按键点击事件三种实现方法
  • fiddler抓包工具与requests库构建自动化报告
  • Hello World C#
  • uniapp强制修改radio-group内单选组件的状态方法
  • deepin V23笔记本电脑安装NVIDIA闭源驱动经验分享
  • 黑马2024AI+JavaWeb开发入门Day02-JS-VUE飞书作业
  • taro使用createAsyncThunk报错ReferenceError: AbortController is not defined
  • qml调用c++类内函数的三种方法
  • 操作系统的设计哲学:Linux与Windows的对比
  • CRMEB 多商户PHP版 v3.1更新内容
  • 探索运维新视界,CMDB的3D机房功能深度解析
  • JVM(七、性能监控、故障处理工具)
  • vue安装步骤
  • JVM指令集概览:基础与应用
  • 讲懂http和https
  • 【AI技术赋能有限元分析应用实践】Abaqus有限元分析与深度学习结合20个案例与有限元分析数据来源方法说明
  • 相交链表和环形链表
  • 力扣做题笔记
  • shell编程5,字符串运算符
  • Sofia-SIP 使用教程
  • 调试android P2P无法正常运行
  • Cesium着色器的创意和方法(六——透明和半透明)