Android自定义控件--评分星级View

Android自定义View实现商品评价星星评分控件 先上图看实现效果: 首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性,只定义三个,有间距、分值和是否可以编辑:<!--StarLinearLayout--> <declare-styleable name="star"> <attr name="margin" format="dimension|reference"/> 阅读详情
在开发电商项目中经常都会遇到一些星级评分控件的需求,有需求就必然有开发。废话不多说,没图没真相,上图:

image

确定需求:

  • 可以控制子item之间的边距
  • 自定义选中图片和未选中图片
  • 摆放纵向或者横向
  • 可选择选中数量

基本绘制流程:

  • 1 自定义属性
<!--星星控件属性-->
    <declare-styleable name="StarBarView">
        <!--设置星星间的间隔-->
        <attr name="space_width" format="dimension" />
        <!--星星间宽度-->
        <attr name="star_width" format="dimension" />
        <!--星星间高度-->
        <attr name="star_height" format="dimension" />
        <!--最大数量-->
        <attr name="star_max" format="integer" />
        <!--选中数量-->
        <attr name="star_rating" format="float" />
        <!--未选中图片-->
        <attr name="star_hollow" format="reference" />
        <!--选中图片-->
        <attr name="star_solid" format="reference" />
        <!--是否可以滑动改变选中数量-->
        <attr name="star_isIndicator" format="boolean" />
        <!--排列方向-->
        <attr name="star_orientation" format="enum">
            <enum name="vertical" value="1" />
            <enum name="horizontal" value="0" />
        </attr>
    </declare-styleable>
  • 2 构造函数中获取自定义属性值
    //星星水平排列
    public static final int HORIZONTAL = 0;
    //星星垂直排列
    public static final int VERTICAL = 1;
    //实心图片
    private Bitmap mSolidBitmap;
    //空心图片
    private Bitmap mHollowBitmap;
    private Context context;
    //最大的数量
    private int starMaxNumber;
    private float starRating;
    private Paint paint;
    private int mSpaceWidth;//星星间隔
    private int mStarWidth;//星星宽度
    private int mStarHeight;//星星高度
    private boolean isIndicator;//是否是一个指示器(用户无法进行更改)
    private int mOrientation;

    public StarBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StarBarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        paint = new Paint();
        this.context = context;
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StarBarView, defStyle, 0);
        mSpaceWidth = a.getDimensionPixelSize(R.styleable.StarBarView_space_width, 0);
        mStarWidth = a.getDimensionPixelSize(R.styleable.StarBarView_star_width, 0);
        mStarHeight = a.getDimensionPixelSize(R.styleable.StarBarView_star_height, 0);
        starMaxNumber = a.getInt(R.styleable.StarBarView_star_max, 0);
        starRating = a.getFloat(R.styleable.StarBarView_star_rating, 0);
        mSolidBitmap = getZoomBitmap(BitmapFactory.decodeResource(context.getResources(), a.getResourceId(R.styleable.StarBarView_star_solid, 0)));
        mHollowBitmap = getZoomBitmap(BitmapFactory.decodeResource(context.getResources(), a.getResourceId(R.styleable.StarBarView_star_hollow, 0)));
        mOrientation = a.getInt(R.styleable.StarBarView_star_orientation, HORIZONTAL);
        isIndicator = a.getBoolean(R.styleable.StarBarView_star_isIndicator, false);
        a.recycle();
    }
  • 3 获取图片bitmap,设置宽高
/**
     * 获取缩放图片
     *
     * @param bitmap
     * @return
     */
    public Bitmap getZoomBitmap(Bitmap bitmap) {
        if (mStarWidth == 0 || mStarHeight == 0) {
            return bitmap;
        }
        // 获得图片的宽高
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        // 设置想要的大小
        int newWidth = mStarWidth;
        int newHeight = mStarHeight;
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        return newbm;
    }
  • 4 onMeasure函数测量子控件大小,然后设置当前控件大小
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mOrientation == HORIZONTAL) {
            //判断是横向还是纵向,测量长度
            setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
        } else {
            setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
        }
    }

    private int measureLong(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if ((specMode == MeasureSpec.EXACTLY)) {
            result = specSize;
        } else {
            result = (int) (getPaddingLeft() + getPaddingRight() + (mSpaceWidth + mStarWidth) * (starMaxNumber));
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureShort(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = (int) (mStarHeight + getPaddingTop() + getPaddingBottom());
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }
  • 5 确定好数据后开始描绘bitmap到Canvas上
@Override
    protected void onDraw(Canvas canvas) {
        if (mHollowBitmap == null || mSolidBitmap == null) {
            return;
        }
        //绘制实心进度
        int solidStarNum = (int) starRating;
        //绘制实心的起点位置
        int solidStartPoint = 0;
        if (mOrientation == HORIZONTAL)
            for (int i = 1; i <= solidStarNum; i++) {
                canvas.drawBitmap(mSolidBitmap, solidStartPoint, 0, paint);
                solidStartPoint = solidStartPoint + mSpaceWidth + mSolidBitmap.getWidth();
            }
        else
            for (int i = 1; i <= solidStarNum; i++) {
                canvas.drawBitmap(mSolidBitmap, 0, solidStartPoint, paint);
                solidStartPoint = solidStartPoint + mSpaceWidth + mSolidBitmap.getHeight();
            }
        //虚心开始位置
        int hollowStartPoint = solidStartPoint;
        //多出的实心部分起点
        int extraSolidStarPoint = hollowStartPoint;
        //虚心数量
        int hollowStarNum = starMaxNumber - solidStarNum;
        if (mOrientation == HORIZONTAL)
            for (int j = 1; j <= hollowStarNum; j++) {
                canvas.drawBitmap(mHollowBitmap, hollowStartPoint, 0, paint);
                hollowStartPoint = hollowStartPoint + mSpaceWidth + mHollowBitmap.getWidth();
            }
        else
            for (int j = 1; j <= hollowStarNum; j++) {
                canvas.drawBitmap(mHollowBitmap, 0, hollowStartPoint, paint);
                hollowStartPoint = hollowStartPoint + mSpaceWidth + mHollowBitmap.getWidth();
            }
        //多出的实心长度
        int extraSolidLength = (int) ((starRating - solidStarNum) * mHollowBitmap.getWidth());
        Rect rectSrc = new Rect(0, 0, extraSolidLength, mHollowBitmap.getHeight());
        Rect dstF = new Rect(extraSolidStarPoint, 0, extraSolidStarPoint + extraSolidLength, mHollowBitmap.getHeight());
        canvas.drawBitmap(mSolidBitmap, rectSrc, dstF, paint);
    }
  • 6 最后通过onTouchEvent方法去监听事件
@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isIndicator) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (mOrientation == HORIZONTAL) {
                        float TotalWidth = starMaxNumber * (mStarWidth + mSpaceWidth);
                        if (event.getX() <= TotalWidth) {
                            float newStarRating = (int) event.getX() / (mStarWidth + mSpaceWidth) + 1;
                            setStarRating(newStarRating);
                        }
                    }else{
                        float TotalHeight = starMaxNumber * (mStarHeight + mSpaceWidth);
                        if (event.getY() <= TotalHeight) {
                            float newStarRating = (int) event.getY() / (mStarHeight + mSpaceWidth) + 1;
                            setStarRating(newStarRating);
                        }
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
//                    float starTotalWidth = starMaxNumber * (mStarWidth + mSpaceWidth);
//                    if (event.getX() <= starTotalWidth) {
//                        float newStarRating = (int) event.getX() / (mStarWidth + mSpaceWidth) + 1;
//                    setStarRating(newStarRating);
//                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                case MotionEvent.ACTION_CANCEL:
                    break;
            }
        }
        return super.onTouchEvent(event);
    }

如何使用:

  • xml布局
<com.caption.starbarexample.widget.StarBarView
        android:id="@+id/sbv_starbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_margin="10dp"
        app:space_width="1dp"
        app:star_height="25dp"
        app:star_hollow="@mipmap/ic_star_yellow_normal"
        app:star_isIndicator="false"
        app:star_max="5"
        app:star_orientation="horizontal"
        app:star_rating="2"
        app:star_solid="@mipmap/ic_star_yellow_selected"
        app:star_width="25dp" />
  • 代码添加
    //拿到当前星星数量
    mStarbar.getStarRating();

github:https://github.com/GHdeng/StarBarExample

Android 星级评分条的基本用法 一 、效果如图所示: 布局代码实现: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/t 阅读详情

相关推荐

Android星级评分条设计与实现

本文还有配套的精品资源,点击获取 简介:星级评分条是Android开发中常用的UI元素,用于收集用户反馈。本示例深入探讨了RatingBar的使用方法,包括XML布局声明、属性详解、编程接口、监听评分变化、自定义样式和示例代码。通过本课程,开发者可以掌握RatingBar的实际应用,提升用户体验。 1. Android星级评分条简介 星级评分条是一个常用的控...

weixin_36364707的博客 1482

推荐开源项目:StarRatingView - 简洁易用的Android星星评分视图

推荐开源项目:StarRatingView - 简洁易用的Android星星评分视图 去发现同类优质开源项目:https://gitcode.com/ 在移动应用开发中,给用户提供一种便捷的方式来表达他们的反馈或评价是非常常见的需求。 是一个为 Android 平台设计的轻量级库,它允许开发者快速集成一颗颗闪烁的星星评级视图,为你的应用增添美观且互动性强的评分功能。 项目简介 StarRating...

gitblog_00028的博客 550

Android自定义星星评分控件

http://blog.youkuaiyun.com/a756213932/article/details/51939422 博客详细说明

Android 基础知识4-3.9 RatingBar(星级评分条)详解

RatingBar是基于SeekBar和ProgressBar的扩展,用星型来显示等级评定。使用RatingBar的默认大小时,用户可以触摸/拖动或使用键来设置评分,它有两种样式(小风格用ratingBarStyleSmall,大风格用ratingBarStyleIndicator),其中大的只适合指示,不适合于用户交互。当使用可以支持用户交互的RatingBar时,无论将控件(widgets)放在它的左边还是右边都是不合适的。

yyxhzdm的博客 1757

将CityScapes数据集转换为COCO格式的实例分割数据集

##¥##2019年结束前最后两小时,写出本年度最后一篇博客,不是博主没地方去跨年,实在是Coding乐趣无穷ahhhh ##¥## COCO数据集是研究实例分割的通用数据集,但是针对道路环境的数据较少,对于自动驾驶和移动机器人的应用并不适配。而提供道路环境的实例分割数据的数据集目前有KITTI、CityScapes、Apllo等,CityScapes算是应用较广,数据质量较高的一个,所以,本篇...

陆羽飞的博客 9940

别再手动续期SSL证书了!用acme.sh配合阿里云DNS API,实现全自动HTTPS证书管理

本文详细介绍了如何使用acme.sh配合阿里云DNS API实现SSL/TLS证书的全自动管理,彻底解决手动续期带来的风险与不便。通过自动化部署流程,包括环境准备、API集成、多域名证书申请等关键步骤,帮助运维人员构建高效、可靠的HTTPS证书管理体系,显著提升安全性和运维效率。

weixin_29200485的博客 271

推荐开源项目:StarRatingView - 一款优雅的Android评分视图库

推荐开源项目:StarRatingView - 一款优雅的Android评分视图库 在开发Android应用时,我们经常需要实现用户评价或显示商品评分的功能,这时候一个简洁而强大的评级视图组件就显得尤为重要。今天要向大家推荐的是,一个由王超iOS开发并开源的Android星标评级视图库。 项目简介 StarRatingView是一个轻量级、高度可定制的Android库,它允许开发者轻松地添加动态星...

gitblog_00073的博客 597

Python实战:如何用高德API批量获取POI数据(附完整代码)

本文详细介绍了如何使用Python通过高德API批量获取POI数据,包括API基础准备、核心功能模块设计、高级功能实现及实战应用案例。文章提供了完整代码示例,帮助开发者高效解决商业网点分析、公共设施规划等实际项目中的数据采集需求。

stem5的博客 326

星星评价控件android开发_android自定义星级评分控件,可实现只显示实心星星

话不多说,上图近日app需求弄一个等级展示,看了下UI图,只显示实星(点亮的星星).如图但是网上关于星级评分的例子大多这样也展示虚心星星通过自定义Viewpackage com.starsbar;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;im...

weixin_39865625的博客 238

第95节:多模型多卡推理管理

多模型推理:在同一硬件平台上同时部署多个不同或相同的深度学习模型,满足多任务需求。多卡推理:利用多块 GPU 资源,提升推理吞吐量与并发能力。目标:合理分配 GPU 资源,实现高效、低延迟的推理服务。

yumeiguo的博客 218

GeoServer下载与安装(详细图文教程)

GeoServer官方版可以方便的发布地图数据,允许用户对特征数据进行更新、删除、插入操作,通过 GeoServer 可以比较容易的在用户之间迅速共享空间地理信息。

大剑师兰特的GIS世界 3276

android自定义星级评分控件,可实现只显示实心星星

话不多说,上图 近日app需求弄一个等级展示,看了下UI图,只显示实星(点亮的星星).如图 但是网上关于星级评分的例子大多这样 也展示虚心星星 通过自定义View package com.starsbar; import android.content.Context; import android.content.res.TypedArray; import android.graphic...

每一件自己觉得值得的事都要不留余力的去做 2596

反爬虫:对抗最新反爬技术 Cloudflare详解

本文针对Cloudflare最新反爬机制提供完整解决方案,覆盖TLS指纹、行为轨迹、设备指纹等检测场景。文章首先分析Cloudflare的三重检测体系(TLS指纹、行为指纹、设备指纹)及其拦截表现,随后提出四种绕过方案:1)使用curl_cffi模拟浏览器TLS指纹;2)通过undetected-chromedriver移除自动化特征;3)Playwright结合stealth插件模拟人类行为;4)动态请求调度策略。重点推荐轻量级Python方案curl_cffi和浏览器自动化方案Playwright-st

数据知道的博客 4626

Android学习总结之自定义View实战篇

自定义view的实战篇

2301_80329517的博客 621

【逐函数讲解ORB_SLAM3源码】获取普通帧率、关键帧、IMU数据

获得imu的旋转 mRwc * mImuCalib.mTcb.rotationMatrix(); Sophus::SE3 mTwc 创建ORB_SLAM3系统 Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_RGBD, true, 0, file_nam

小秋 AI SLAM 入门实战教程 1245

用 SAP XCO XLSX 模块优雅读 Excel:坐标、选择模式与实战案例全解析

SAP ABAP Cloud 中的 XCO XLSX 模块为 Excel 文件处理提供了官方解决方案。文章介绍了三个核心概念:通过 XCO_CP_XLSX=>DOCUMENT 获取文档句柄;使用 CL_XCO_XLSX_COORDINATE 坐标系统定位单元格;利用 Selection Pattern 精确读取数据区域。这些功能在 RAP 批量导入等业务场景中尤为实用,相比传统方案更加简洁可靠。文章还分享了真实项目中的最佳实践,如动态列定位和相对偏移技巧,帮助开发者构建更健壮的 Excel 导入逻辑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 193

安卓评星条_android自定义星级评分控件,可实现只显示实心星星

释放双眼,带上耳机,听听看~!话不多说,上图近日app需求弄一个等级展示,看了下UI图,只显示实星(点亮的星星).如图但是网上关于星级评分的例子大多这样也展示虚心星星通过自定义Viewpackage com.starsbar;import android.content.Context;import android.content.res.TypedArray;import android.gra...

weixin_39805364的博客 230

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android 自定义星级评分控件

自定义Android 星级评分控件,先上一下效果图 关于控件的制作步骤: 1.首先要确定控件所需要用到的属性,那位作为一个星级评分的控件,能想到的就是大小,形状,数量,评分设置标准,是否允许点击操作,监听等内容,所以我定义了以下属性 public class Star extends View { //星星评分 private float starMark = 0.0F;

z690798364的专栏 3769

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

摸鱼学Android 十二(控件2)

摸鱼学Android 十二UI控制之二1 ProgressBar(进度条)1.1 基本属性1.2 自定义圆形进度条2 SeekBar(拖动条)2.1 基本属性2.2 监听事件3 RatingBar(星级评分条)3.1 基本属性3.2 监听事件3.3 自定义星级图标 UI控制之二 1 ProgressBar(进度条) 1.1 基本属性 max:进度条最大值 progress:当前进度值 progressDrawable:轨道资源图片 indeterminate:设置不确定模式,为true则进度条动画无限循环

qq_23470315的博客 238

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android开发自学笔记(Android Studio)—4.5 ProgressBar及其子类

一、前言 ProgressBar本身代表了进度条组件,它还派生出了两个常用的组件:SeekBar和RatingBar,他们的使用方法类似,只是显示界面有一定的区别。我们看一下API文档中的说明: 从图中我们是可以直接看到ProgressBar继承自View类,直接子类有AbsSeekBar和ContentLoadingProgressBar,间接子类有RatingBar和Seek...

angdian2335的博客 316

Android程序里加星级评分,Android 自定义星级评分控件

自定义Android 星级评分控件,先上一下效果图 关于控件的制作步骤:1.首先要确定控件所需要用到的属性,那位作为一个星级评分的控件,能想到的就是大小,形状,数量,评分设置标准,是否允许点击操作,监听等内容,所以我定义了以下属性public class Star extends View {//星星评分private float starMark = 0.0F;//星星个数private int...

weixin_29070861的博客 790

Android UI控件学习(二)——星级评分条

Android UI控件学习(二)——星级评分条开篇自述正文——星级评价条实例项目结构具体代码参考运行效果结语 开篇自述 星级评分条与拖动条类似,都允许用户拖动来改变进度,所不同的是,星级评分条通过星星图案表示进度。通常情况下,使用星级评分条表示对某一事物的支持度或某种服务的满意程度等。 因为我上一篇拖动条已经详细介绍过了,这里就简单写了,如果有不懂的,可以先去看一下我上一篇拖动条的那篇文章。 正...

lzfengluo的博客 1005

星级评分条控件

布局代码:完整代码:public class MainActivity extends Activity {    private RatingBar ratingBar;//星级评分条 @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    se...

Beginniqg 681

安卓评星条_Android实现根据评分添加星级条

简述在仿写豆瓣的时候,发现了根据评分不同,星级数也不同的星级条。百度一搜,发现Android有自带控件UIRatingBar,而iOS得要自己写…好吧,那就写吧。图片素材首先,要准备三张图片,图片如下:空星,半星,全星因为我们可以看到,在豆瓣的评分星级条里,只有空、半、全星,所以只需要准备这3种图片。思路豆瓣的星级条中既有图片,又有文字,所以我们自定义一个继承于UIView的starView。初始...

weixin_39764603的博客 296

android五星菜单,Android获取星级评分的分值

码农公社 210.net.cn210= 102410月24日一个重要的节日--码农(程序员)节效果实现将布局改为LinearLayout,并通过android:orientation="vertical">设置为垂直布局,然后添加一个RatingBar,并通过android:rating="5"设置其星数为5然后再添加一个Button,分别给他们添加Id。xmlns:app="ht...

weixin_36081109的博客 459

HoRain云--Android RatingBar星级评分条使用指南

本文介绍了Android中RatingBar(星级评分条)的基本使用和定制方法。首先讲解了RatingBar的基本属性,包括显示星星数量、默认评分值等,并提供了事件处理的代码示例。随后详细说明了如何自定义评分图标,通过创建layer-list文件和定义style样式,将默认星星替换为自定义表情图标。最后提醒开发者注意图标间距处理,并总结了RatingBar与SeekBar的相似性。文章内容简明实用,适合Android开发者快速掌握RatingBar的使用技巧。

sinat_57153473的博客 841
上一篇: ARGB与RGB、RGBA的区别
下一篇: 使用广播监听网络变化
caption_deng
博客等级 码龄11年 2粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caption_deng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值