Android自定义评分控件:RatingStarView
RatingStarView
Android自定义的评分控件,类似RatingBar那样的,使用星星图标(full、half、empty)作为rating值的“评分/打分控件”。
效果图
图1:
RatingStarView控件支持的特性:

- 半颗星支持(实际支持任意小数)
- 填充色、底色、描边色
- 指定高度,宽度自适应
- 拐角弧度、描边宽度、星星间距
- 肥胖指数(star thickness),越胖越可爱
- 点击评分(不支持半颗星)
实现思路
下面是RatingStarView的实现设计。
如何画一颗星
Star标准坐标
可以在抽象的xOy坐标系中计算得到一个star的“标准坐标”。这个坐标可以作为后续有关坐标计算(偏移和缩放)的基准。
图2:

以上面的图为例,这里其中心点O为原点。
这里为了描述方便,称A,B,C,D,E为5个外点(Outer Corner Vertex),a,b,c,d,e 五个点为内点(Inner Corner Vertex)。
这里坐标值的选取完全出于计算方便来考虑,实现方式毕竟很多,大家可以选取其它坐标方式,比如原点O的位置在其它处,或者星星的范围由高度、宽度表示等。
5个外顶点
A拐点的坐标为(0,1),其它几个点的坐标根据几何公式是可以固定下来的。为了简化计算,可以将这几个值作为常量保存,之后的其它值的计算基于它们。下面代码为了程序上的便利E点坐标x,y值是起始元素:
private static final float[] starVertexes = new float[]{
-0.9511f, 0.3090f, // E (left)
0.0000f, 1.0000f, // A (top vertex)
0.9511f, 0.3090f, // B (right)
0.5878f, -0.8090f, // C (bottom right)
-0.5878f, -0.8090f, // D (bottom left)
};
使用常量简化五角星坐标计算时的cos、sin操作。因为几何上这些点的坐标是固定的。之后可以通过简单的+-*/操作来变换坐标系,以及star的大小。
常量也不会保持得太多,比如a,b,c,d,e的计算是根据A,B,C,D,E来的。
5个内拐点
这里为star引入“胖度系数(star thickness)”的说法,用来控制星星的可爱程度。
很明显,胖度是由a,b,c,d,e五个内点的位置决定的。
但在计算上,这里采取另一种方式:
设置变量thickness来表示肥胖系数,5个内点的位置由原点O和此内点临近的两个外点计算得到。
还是上面的图2,
AE的中点是P,那么e肯定在OP上,如果取OP上的其它点,作为EPA这样的多边形路径(其它五个内点类似)就可以打造出不同肥胖度的星星了。
这里因为原点O是星星的中心,在标准坐标系下,根据胖度系数thickness,结合ABCDE这几个外点,就可以计算出abcde这几个内点了,而且当thickness不同时,星星胖度不同。
根据thickness和ABCDE计算abcde的过程必须是在“标准坐标系”下,也就是X+轴向右,Y+向上,而且O原点是星星中心!!
坐标转换
每一个要显示的star由一个StarModel类来表示,它持有一个星星的坐标信息并完成相应的计算。
其代码是整个RatingStarView关于坐标部分的核心,完整代码见下面的源码地址。
拐点(顶点)表示
星星的顶点可以用一个PointF进行表示,不过这里为了方便将多个点作为一个链表使用,定义了下面的VertexF来保存顶点数据:
class VertexF {
public VertexF() {
}
public VertexF(float x, float y) {
this.x = x;
this.y = y;
}
public float x;
public float y;
public VertexF next;
}
10个拐点的计算
StarModel类使用静态的数组保存ABCDE五个外点的标准坐标系下的坐标初始值。
因为thickness系数必须在标准坐标系下计算,这里选择StarModel的构造函数中接受thickness参数,而且初始化中完成所有10个拐点的计算。
转换到Android坐标系
手机设备下,Android的Y+是向下的,所以需要一个adjustCoordinate()的方法来完成星星坐标系的转换。
同时它还将星星的x,y都变为正数——这样它才是可见的。
注意Android中,childView绘制自身内容时,其使用的x,y坐标单位是pixel,而且是相对其父ViewGroup的相对坐标。
偏移和缩放
RatingStarView在显示若干个star时,需要可以控制其位置和大小。
所以StarModel在标准坐标系转换完为Android下坐标系后(在父布局中的相对坐标),还需要可以被偏移和缩放。
偏移
只需要对10个拐点坐标进行+、-操作即可。
有关Star的大小这里使用height来衡量,因为绘制肯定是完整的星星,这样height和width是有一个比例的。选取height或width作为其大小衡量本身都可以。
缩放
首先以star的height作为衡量,那么在标准坐标系进行转换后可以认为star是具备一个默认的缩放系数的:就是它的高度AD(或AC)线段的垂直距离。
之后要为star设置新的高度时(也就是改变其大小范围——外接矩形边框outerRect),根据高度的变化进行乘除运算即可——要注意的是坐标问题,这个留给写代码时思考。
Android自定义评分控件:RatingStarView的更多相关文章
- Android自定义日历控件(继承系统控件实现)
Android自定义日历控件(继承系统控件实现) 主要步骤 编写布局 继承LinearLayout设置子控件 设置数据 继承TextView实现有圆圈背景的TextView 添加Attribute 添 ...
- Android星星评分控件RatingBar的使用
在Android的开发中,有一个叫做评分控件RatingBar,我们可以使用该控件做等级划分.评分等作用,星星形状显示,也可以半星级别,我们来看一下评分控件如何使用. 布局文件中定义控件以及属性,这里 ...
- android自定义倒计时控件示例
这篇文章主要介绍了Android秒杀倒计时自定义TextView示例,大家参考使用吧 自定义TextView控件TimeTextView代码: 复制代码 代码如下: import android.co ...
- Android自定义组合控件详细示例 (附完整源码)
在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...
- 014 Android 自定义组合控件
1.需求介绍 将已经编写好的布局文件,抽取到一个类中去做管理,下次还需要使用类似布局时,直接使用该组合控件的对象. 优点:可复用. 例如要重复利用以下布局: <RelativeLayout an ...
- Android自定义用户控件简单范例(二)
对于完全由后台定制的控件,并不是很方便其他人的使用,因为我们常常需要看到控件放到xml界面上的效果,并根据效果进行布局的调整,这就需要一个更加标准的控件制作流程: 我们的自定义控件和其他的控件一样,应 ...
- (转)android自定义组合控件
原文地址:http://mypyg.iteye.com/blog/968646 目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性. 1.控件布局:以Linea ...
- android 自定义组合控件 顶部导航栏
在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同.为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件. 例下图: 点 ...
- Android自定义view控件
转载自: http://blog.163.com/ppy2790@126/blog/static/103242241201382210910473/ 开发自定义控件的步骤: 1.了解View的工作原理 ...
随机推荐
- python3.6 简单爬虫
# coding='UTF-8' from bs4 import BeautifulSoup # 引入beautifulsoup 解析html事半功倍 import re import urllib ...
- malloc函数及用法
动态存储分配在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变.C语言中不允许动态数组类型.例如:int n;scanf("%d",&n);int a[n ...
- 于普通用户启动UAC问题
在VS中设置UAC级别操作如下: 项目属性-配置属性-连接器-清单文件 1.UAC执行级别: aslnvoker: 权限级别最低,不需要管理员身份. highestAvailable:获取最高权限执行 ...
- javascript 类型的判断
在平常写js代码,类型判断必不可少,那么我们常见有哪几种?看到了标题,先不看你会想到那些方法 ,常用呢些呢?那么今天我自己总结一些判断类型的判断,如有错,万望告知! 1:typeof 常用这种方法不错 ...
- 性能调优:mysql之left join
poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...
- 老李分享:jvm垃圾回收
老李分享:jvm垃圾回收 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478 ...
- jquery的冒泡事件event.stopPropagation()
js中的冒泡事件与事件监听 冒泡事件 js中“冒泡事件”并不是能实际使用的花哨技巧,它是一种对js事件执行顺序的机制,“冒泡算法”在编程里是一个经典问题,冒泡算法里面的冒泡应该 说是交换更加准确:js ...
- 封装Echarts
项目中需要对数据进行图形展示,例如展示柱状图.饼状图等.这类的前端展示脚本很多,常见的是HighCharts和Echarts.HighCharts是基于svg技术的,而echarts基于Echarts ...
- package(1):tm
tm包是R语言中为文本挖掘提供综合性处理的package,进行操作前载入tm包,vignette命令可以让你得到相关的文档说明.使用默认安装的R平台是不带tm package的,在安装的过程中,它会 ...
- node.js前后台交互示例 -- 使用node.js实现用户注册功能
node.js环境自行搭建,参考菜鸟教程的node.js就可以. 1 通过ajax提交index.html中form表单 register.html文件如下: <!doctype html> ...