此篇为我的第一篇博客,借此平台让更多的人知道和掌握更多android的知识,希望能越来越优秀.高手过招,不只是会用,更多的是理解它的原理,能举一反三,与已知知识对比学习,方便记忆与理解,下面,我们直接进入正题.我的文章会有一个很明显的特征,就是中学时期老师所讲的"3W"原则,what(是什么),how(怎么用),why(为什么要用这个?,原因是什么?).Let's go~
自定义View是成为android高手的必经之路,期间,遇到了很多很多这样那样的问题,好记性不如烂笔头,养成写博客的习惯能让我们更上一层楼,加深记忆与理解,好东西是需要拿出来分享的,能引来更多人的交流与讨论,共同学习与进步,好了,这下真的进入主题了.
本篇文章讲的正如标题,是Rect的使用与理解.
Rect就是用来存放坐标的地方,android用它来表示一个矩形,怎么表示呢,总结来说就是用左上角的坐标和右下角的坐标来表示一个矩形.
来看官方api:
来看红色部分:
1.大多数的方法都不会去检查这个矩形的坐标(左边坐标是否小于右边坐标,底部坐标是否大于顶部坐标,这在我们认为看来似乎是默认的,可是程序却不是这样的)
2.右边和底部的坐标是独立的,这意味着被画的矩形是从所给的顶部坐标和左边的坐标开始画的(左上角),而不是右边和底部坐标开始画的(右下角),看起来好像就是从左上角开始画到右下角.
对于刚接触的你来说可能看不懂吧,不着急,只是带你看一遍api,接下来带你理解.
咱们再来看一下构造函数:(api很权威,面向api编程也是一个不错的选择哦)
哈,总共就只有三个,一目了然:
1.创建一个空的Rect
2.根据left,top,right,bottom创建
3.根据另一个Rect创建,也就是复制它的坐标(可以这么理解)
1和3就不用多说了吧,下面用一幅图简单明了的告诉你是什么意思
此处A(left,top)->(10,10),D(right,bottom)->(110,110),就是这么简单~
所以,在new一个Rect的时候,把D坐标当做左上角,把A当做右下角坐标也是可以的.不信你可以试试:
让我们来进一步看它的方法:
我们来看几个重要的,toString()这些就不多介绍了,自行尝试
1.sort()方法:
上面说过,在new一个Rect的时候,左边是可以大于右边的,顶部也是可以大于底部的,也就是说是可以"乱来的",那对于我们认为的理论来说,都是左上角坐标在先,然后画到右下角去,这时就可以用到sort()方法,你可以看他的源码,其实也只是一个比较大小并且交换位置的做法,无非就是让它从左上角画到右下角
输出:
可以看到调用sort之后,把思维方式改为了我们所更好理解的
2.contains()方法:
第一:判断这四个点的坐标的矩形是否在包括在原来矩形之中
第二:无非就是第一种方法重新new一个矩形来比较
第三:判断这个点是否在矩形中,这些就不演示了,简单
3.union()方法:
跟方法名一样,表示合并矩形
4.setIntersect(Rect a, Rect b)方法
求两个矩形的交集
5.Intersect()
返回两个矩形是否相交,是否有共同的部分
6.offset(int dx, int dy)
相对偏移,也就是说dx正的表示向右移动多少,负的表示像左移动多少,dy表示的含义相同,这里要注意的是y轴是向下增长的,跟数学上的不同.
7.offsetTo(int newLeft, int newTop)
绝对偏移,将左上角的坐标移动到绝对的一个位置,两个参数分别代表左边新坐标和顶部新坐标
现在来解释上面api中画红线的地方:
1.也就是说new一个Rect的时候是不被排序的,要排序需要调用sort方法
2.右下角的坐标其实是不包含在矩形中的,java很多设计都是前闭后开的,也就是数学中的[x,y)
不信,来看:
Rect rect = new Rect(10, 10, 100, 100);
Log.i(TAG, "onDraw: " + rect.contains(10, 100));//这里会输出false
其实right和bottom都是失效的,可以理解为右边和底部的那两条边其实是不包含在这个矩形中的,所以尽量不要使用右下角的坐标.
3.虽然right和bottom是不包括的,但是width()和height()是可用的,centerX和centerY也是可用的,java的思想有时候就是这么奇葩的~
最后,给出Rect和RectF的区别:
只不过是精度不同罢了,Rect的精度是int,RectF的精度是float,其他都是差不多的,Point和PointF的区别主要也是如此
最后,给出测试用的代码:
MyRect.java
public class MyRect extends View {
private static final String TAG = "MyRect";
private Paint mRectPaint;
public MyRect(Context context) {
this(context, null);
}
public MyRect(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyRect(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initControl();
}
private void initControl() {
mRectPaint = new Paint();
mRectPaint.setColor(Color.YELLOW);
mRectPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect(100, 100, 10, 100);
rect.sort();
// Rect rect2 = new Rect(20,20,200,200);
// 合并矩形
// rect.union(rect2);
// 取交集
// rect.setIntersect(rect,rect2);
// 是否包含矩形
// rect.contains(rect2);
// 绝对偏移
// rect.offsetTo(50,50);
// 相对偏移,往x轴方向移动多少以及往y轴方向移动多少
// rect.offset(10,10);
canvas.drawRect(rect, mRectPaint);
}
}
这里先不给出具体的解释,给出简单的解释:(主要用于测试Rect类,此篇不讨论自定义View)
1.继承View,给出三个构造函数,在构造函数中初始化画笔
2.重写onDraw方法,这里已经给了Canvas(画布)对象,我们暂时只需要知道drawRect方法就可以了
3.在安卓中尽量用log日志的方法来打印你需要测试的东西,或者用断点调试,不要用System.out.println()这种java的方式来打印日志
xml文件:
ok,到此,结束,现在看来是不是这个Rect也不过如此嘛~so easy~
如有错误或者疑问,欢迎评论提问指出,也可以加我的微信15158004599或者邮箱[email protected]共同交流安卓以及java的一些知识,谢谢!
至于为什么要使用Rect,就不需要我多说了吧,用来画出矩形,后面即将会学习到Canvas中用Rect以及RectF来画弧度,圆,线,根据路径画等等更多更丰富的内容,敬请期待,下期再见~