1. 程式人生 > >自定義View之Rect的使用與理解

自定義View之Rect的使用與理解

此篇為我的第一篇部落格,藉此平臺讓更多的人知道和掌握更多android的知識,希望能越來越優秀.高手過招,不只是會用,更多的是理解它的原理,能舉一反三,與已知知識對比學習,方便記憶與理解,下面,我們直接進入正題.我的文章會有一個很明顯的特徵,就是中學時期老師所講的"3W"原則,what(是什麼),how(怎麼用),why(為什麼要用這個?,原因是什麼?).Let's go~

自定義View是成為android高手的必經之路,期間,遇到了很多很多這樣那樣的問題,好記性不如爛筆頭,養成寫部落格的習慣能讓我們更上一層樓,加深記憶與理解,好東西是需要拿出來分享的,能引來更多人的交流與討論,共同學習與進步,好了,這下真的進入主題了.

本篇文章講的正如標題,是Rect的使用與理解.

Rect是什麼?

Rect就是用來存放座標的地方,android用它來表示一個矩形,怎麼表示呢,總結來說就是用左上角的座標和右下角的座標來表示一個矩形.

來看官方api:

來看紅色部分:

1.大多數的方法都不會去檢查這個矩形的座標(左邊座標是否小於右邊座標,底部座標是否大於頂部座標,這在我們認為看來似乎是預設的,可是程式卻不是這樣的)

2.右邊和底部的座標是獨立的,這意味著被畫的矩形是從所給的頂部座標和左邊的座標開始畫的,而不是右邊和底部座標開始畫的,看起來好像就是從左上角開始畫到右下角.

對於剛接觸的你來說可能看不懂吧,不著急,只是帶你看一遍api,接下來帶你理解.

Rect怎麼用?

咱們再來看一下建構函式:(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檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <xhj.zime.com.blogrect.MyRect
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

ok,到此,結束,現在看來是不是這個Rect也不過如此嘛~so easy~

如有錯誤或者疑問,歡迎評論提問指出,也可以加我的微信15158004599共同交流安卓以及java的一些知識,謝謝!

至於為什麼要使用Rect,就不需要我多說了吧,用來畫出矩形,後面即將會學習到Canvas中用Rect以及RectF來畫弧度,圓,線,根據路徑畫等等更多更豐富的內容,敬請期待,下期再見~