自定义View之Rect的使用与理解

此篇为我的第一篇博客,借此平台让更多的人知道和掌握更多android的知识,希望能越来越优秀.高手过招,不只是会用,更多的是理解它的原理,能举一反三,与已知知识对比学习,方便记忆与理解,下面,我们直接进入正题.我的文章会有一个很明显的特征,就是中学时期老师所讲的"3W"原则,what(是什么),how(怎么用),why(为什么要用这个?,原因是什么?).Let's go~

自定义View是成为android高手的必经之路,期间,遇到了很多很多这样那样的问题,好记性不如烂笔头,养成写博客的习惯能让我们更上一层楼,加深记忆与理解,好东西是需要拿出来分享的,能引来更多人的交流与讨论,共同学习与进步,好了,这下真的进入主题了.

本篇文章讲的正如标题,是Rect的使用与理解.

Rect是什么?

Rect就是用来存放坐标的地方,android用它来表示一个矩形,怎么表示呢,总结来说就是用左上角的坐标和右下角的坐标来表示一个矩形.

来看官方api:

自定义View之Rect的使用与理解_第1张图片

来看红色部分:

1.大多数的方法都不会去检查这个矩形的坐标(左边坐标是否小于右边坐标,底部坐标是否大于顶部坐标,这在我们认为看来似乎是默认的,可是程序却不是这样的)

2.右边和底部的坐标是独立的,这意味着被画的矩形是从所给的顶部坐标和左边的坐标开始画的(左上角),而不是右边和底部坐标开始画的(右下角),看起来好像就是从左上角开始画到右下角.

对于刚接触的你来说可能看不懂吧,不着急,只是带你看一遍api,接下来带你理解.

Rect怎么用?

咱们再来看一下构造函数:(api很权威,面向api编程也是一个不错的选择哦)

自定义View之Rect的使用与理解_第2张图片

哈,总共就只有三个,一目了然:

1.创建一个空的Rect

2.根据left,top,right,bottom创建

3.根据另一个Rect创建,也就是复制它的坐标(可以这么理解)

1和3就不用多说了吧,下面用一幅图简单明了的告诉你是什么意思

自定义View之Rect的使用与理解_第3张图片

此处A(left,top)->(10,10),D(right,bottom)->(110,110),就是这么简单~

所以,在new一个Rect的时候,把D坐标当做左上角,把A当做右下角坐标也是可以的.不信你可以试试:

让我们来进一步看它的方法:

自定义View之Rect的使用与理解_第4张图片

自定义View之Rect的使用与理解_第5张图片

我们来看几个重要的,toString()这些就不多介绍了,自行尝试

1.sort()方法:

上面说过,在new一个Rect的时候,左边是可以大于右边的,顶部也是可以大于底部的,也就是说是可以"乱来的",那对于我们认为的理论来说,都是左上角坐标在先,然后画到右下角去,这时就可以用到sort()方法,你可以看他的源码,其实也只是一个比较大小并且交换位置的做法,无非就是让它从左上角画到右下角

输出:

可以看到调用sort之后,把思维方式改为了我们所更好理解的

2.contains()方法:

自定义View之Rect的使用与理解_第6张图片

第一:判断这四个点的坐标的矩形是否在包括在原来矩形之中

第二:无非就是第一种方法重新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来画弧度,圆,线,根据路径画等等更多更丰富的内容,敬请期待,下期再见~

你可能感兴趣的:(自定义View)