天天看點

《Android和PHP開發最佳實踐》一2.8 Android圖形界面

前面介紹了android應用界面(android ui)的相關内容,不過對于一些遊戲應用來說,這些ui控件往往派不上用場。此外,一些特殊的android應用也有可能會使用到比較底層的圖形類庫,是以,本節我們就來學習android的圖形系統。

android系統中的圖形大緻可以分為2d圖形和3d圖形兩類,2d圖形的類庫在android.graphics包下,本節将會重點介紹;3d圖形的類庫在android.opengl包下,由于這部分内容和遊戲開發關系比較緊密,這部分内容将被放在本書第13章中介紹,感興趣的朋友可以提前參考13.1.4節中的内容。

首先,讓我們來想象一下,當我們繪畫的時候,最重要的兩樣東西是什麼?答案應該沒有什麼懸念,那就是畫筆和畫布。實際上,在android系統中繪制圖形的原理是相同的,我們同樣需要先使用程式構造一把畫筆(paint),然後在畫布(canvas)上進行繪畫。

android系統中的畫筆類,即android.graphics包下的paint類,該類包含了一系列的方法與屬性,用于構造繪制圖形用的畫筆。我們把常用的方法歸納到表2-5中。

《Android和PHP開發最佳實踐》一2.8 Android圖形界面

以上方法常用于畫筆初始化的配置邏輯中,接下來讓我們來學習paint畫筆類的使用範例,如參考代碼清單2-28所示。

代碼清單 2-28

以上視圖類testpaintview繼承自view基類,主要的繪制邏輯在ondraw方法中,即使用定制好的實心畫筆繪制一個紅色的矩形,這裡我們可以學習到使用paint畫筆類的正确方法。此外,我們還需要注意,這裡在使用setcolor方法設定畫筆顔色的時候,用到了color類的預定義顔色常量,我們将這些常用的顔色常量歸納到表2-6中。

《Android和PHP開發最佳實踐》一2.8 Android圖形界面

設定好畫筆和顔色,就可以開始在畫布上繪畫了,這時我們就需要用到畫布類,即canvas類。該類包含了一系列的方法與屬性,用于設定畫布的外觀,我們把常用的方法歸納到表2-7中。

canvas類中常用繪制方法的用法比較簡單,android系統已經在view類的ondraw方法中預設傳入了canvas對象,我們可以根據需要使用不同的draw方法繪制出不同的圖形。比如,代碼清單2-29中就使用了drawrect方法繪制了一個矩形。

《Android和PHP開發最佳實踐》一2.8 Android圖形界面

然而,遊戲應用的畫布中通常不隻有一個圖形,通常需要對其中的某些圖形進行特殊處理,比如旋轉、變形等,此時需要先使用save方法來儲存畫布,圖形處理完畢之後再調用restore方法來重置、重繪,使用範例如代碼清單2-29所示。

代碼清單 2-29

以上程式繪制了兩個矩形。其中,紅色的矩形繞着螢幕左上方的頂點順時間旋轉了10°。這裡涉及canvas畫布坐标系的知識,我們将在2.8.3節中介紹。另外,我們還可以學習到如何對canvas畫布進行設定、儲存、旋轉、重置等一系列的操控過程。學習了以上paint和canvas類的程式設計技巧之後,開發者就可以在android應用和遊戲中友善地繪圖了。

前面我們已經學習了畫筆(paint)和畫布(canvas)的基礎知識,接下來我們就可以使用這些工具來畫圖了。實際上,在前面的代碼範例中,我們已經介紹了如何使用canvas對象的drawrect方法來繪制矩形,但是大家可能還不清楚方法中參數值的含義,是以我們先來熟悉canvas畫布的坐标系,如圖2-12所示。

從以上的坐标系示意圖中,我們可以看出以下幾個要點。其一,canvas畫布的坐标原點位于整張畫布的左上方,點坐标為“(0,0)”;其二,螢幕橫向的是x軸,縱向的是y軸,螢幕内的點坐标都是正數;其三,以矩形為例,我們可以看到繪圖方法(drawrect)中的left、top、right、bottom等參數的含義,其他方法中的類似參數的含義都可以依此類推。

另外,在使用canvas進行繪圖的時候還要注意,畫布是按照程式邏輯的先後順序進行渲染的,是以底部圖形的渲染邏輯放在前面,渲染邏輯在後面的圖形則會層層覆寫上去,使用範例請參考代碼清單2-30。

代碼清單 2-30

在上述代碼中,testgraphicsview類的ondraw方法中依次繪制了圓形、矩形、橢圓和多邊形,運作結果如圖2-13所示,我們可以很清楚地看到這些基礎幾何圖形的顯示效果以及圖形渲染的先後順序。

基礎幾何圖形的繪制是android圖形系統的基礎知識。在此基礎之上,我們可以把android ui控件結合到一起,開發出豐富多彩的應用ui界面。當然,我們還可以運用view控件的重新整理機制完成一些簡單的圖形動畫,相關内容将在2.8.4節中介紹。

常見的圖形變換包括位移、旋轉、縮放、傾斜等,其中,位移變換在開發者掌握了畫布坐标系等基礎概念的情況下,實作起來是比較簡單的;然而,旋轉、縮放以及傾斜變換則涉及變換矩陣(matrix)的概念,這裡需要特别解釋一下。

android系統中的變換矩陣實際上是一個3×3的矩陣,專門用于控制圖形變換,矩陣中的每個數值都有其特定的含義。android sdk中的matrix類位于android.graphics包下,我們可以通過setvalue方法直接設定旋轉矩陣的二維數組,但是這種用法比較難懂,更簡單的用法是使用matrix類提供的方法來控制旋轉矩陣,比如setrotate方法就用于設定旋轉的角度。代碼清單2-31就展示了matrix類的用法。

代碼清單 2-31

上述代碼中的testimageview類是一個完整的重繪畫布視圖的例子。首先,該類繼承自view基類,同時還包含了一個線程類的run方法,在該方法的邏輯中,每100ms進行一次重繪,即調用postinvalidate方法通知主線程更新圖像。其次,在testimageview類的構造方法中,主要包含了資源初始化的邏輯,這裡程式加載了一個五星形狀的圖像資源檔案。另外,在ondraw方法中,我們可以看到starmatrix變換矩陣的常見用法之一,即通過setrotate方法設定旋轉的角度。該程式最終的運作效果,就是畫出了一個繞着螢幕左上方順時針旋轉的五角星,如圖2-14所示。

當然,我們還可以讓圖像繞着某個中心點旋轉,這也不是問題,我們隻需要對ondraw方法的邏輯稍做修改即可,修改過的邏輯實作如代碼清單2-32所示。

代碼清單 2-32

要讓圖形繞着其中心旋轉,首先要使用setrotate方法設定圖形的旋轉中心,然後再使用posttranslate方法把圖形平移到相應的位置,即坐标(transx,transy)。該執行個體的運作效果如圖2-15所示,我們可以看到螢幕上出現了一個不斷自轉的五角星。

當然,除了旋轉之外,常見的圖形變換還包括大小變換、傾斜變換等,限于篇幅,這裡就不做介紹了,有興趣的讀者可以參考matrix類文檔中的prescale、postscale、preskew、postskew等方法。這裡我們還需要注意的是pre和post系列方法的差別,帶有pre字首的方法表示此變換邏輯需要應用在所有變換邏輯之前,而帶有post字首的方法則表示此變換邏輯會依次往後排列,是以代碼清單2-28中的旋轉邏輯也可以使用代碼清單2-33中的代碼替代。

代碼清單 2-33