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的工作原理 ... 
随机推荐
- iOS开发之延时执行
			方法1: performSelector(SEL) withObjects:(id) afterDelay:(NSTimeInterval); 方法2: dispatch_after(dispatch ... 
- CSS.01 -- 选择器及相关的属性文本、文字、字体、颜色、
			与html相比,Css支持更丰富的文档外观,Css可以为任何元素的文本和背景设置颜色:允许在任何元素外围设置边框:允许改变文本的大小,装饰(如下划线),间隔,甚至可以确定是否显示文本. 什么是CSS? ... 
- Windows Mobile 常用键值VK对应表
			#define VK_TSOFT2 VK_F2 // Softkey 2 #define VK_TTALK VK_F3 // Talk ... 
- ATL dll注册失败
			“生成”->“生成解决方案”或“重新生成解决方案”,在注册时,报错:regisvr32 /r/c " C:\Users\Administrator\Desktop\复件DrvWater ... 
- Windbg DUMP分析(原创汇总)
			1. 引入篇 所谓技术分享,其实是一个自我总结和相互学习.不断成长的过程. 考虑到之前原创的文章http://www.cnblogs.com/LoveOfPrince/p/6032523.html&l ... 
- linux最常用命令
			1,cd命令 作用:切换当前目录,它的参数切换的路劲,可以是相对路劲,也可以是绝对路劲. 用法: cd /root/Docements #切换当/root/Docements,绝对路劲 cd ./ ... 
- sublime Text3+emmet(快速开发)
			sublime软件使用Emmet插件快速编写CSS样式 基本的CSS样式编写时,很多样式只需输入首字母即可得到不带属性值的CSS样式,像上面说到的margin.而 ... 
- vim中文帮助文档安装
			vim自带的帮助手册是英文的, 对平时编程的人来说没有多大阅读困难,在何况还有"星级译王"呢, 但是我猜和我一样连英语四级都愁的大有人,可偏偏就有一帮好心人人将其翻译成了中文, 可 ... 
- Windows入门基础:1.关于CreateWindow()函数使用中遇到的问题
			我在实现显示窗口的程序中,遇到一个问题:首先程序没有任何语法错误,编译能够通过,但是就是不能弹出窗口. 后来在MSDN中查询CreateWindow()函数,发现了下面这句话: "If lp ... 
- JS滚动加载
			var one = true;//设置一个全局变量 $(window).scroll(function () { var hight = document.body.scrollHeight - do ... 
