Android界面View及ViewGroup

2.1.0 View及ViewGroup類關係
Android View和ViewGroup從組成架構上看,似乎ViewGroup在View之上,View需要繼承ViewGroup,但實際上不是這樣的。 View是基類,ViewGroup是它的子類。這就證明了一點,View代表了用戶界面組件的一塊可繪製的空間塊。每一個View在屏幕上佔據一個長方 形區域。在這個區域內,這個VIEW對象負責圖形繪製和事件處理。View是小控件widgets和ViewGroup的父類。ViewGroup又是 Layout的基類。

image

image


從上面兩圖的對比中,可以看出,實際上ViewGroup是View的子類,因此,View的行爲特徵ViewGroup也具備,但同時因爲 ViewGroup是Layout的祖先,所以具備了其它一些特點,View所未具有的。通常創建一個View,不論是通過XML還是通過代碼創建。對任 何一個View及這個View的子類Widget,需要關注如下幾個方面:
【1】設置屬性,如長、寬、着色等。這些屬性的設置通常可以用代碼實現,也可以用XML文件。並用這些屬性在運行時候也可以通常方法進行修改。
ID 屬性,Android對每個UI元素的ID名稱要求唯一,但也不絕對。同時在不同的Layout中是可以相同的元素名稱的。給一個UI元素指定ID,有一個好處就是可以在代碼中找得到。

image

Tags,同ID不同,這個不用來搜索View,類似於對View的一些描述性數據保存。
Animation,對任何一個View,可以使用動畫對象進行操作。注意,如果View有子的話,子同樣具備這個animation功能
Position, Size, padding and margins,對任一個View來說,表達這個View通常是寬和高。也可以設置padding和margins。不是所有的View都設置margins。

image

Orientatiion,對ViewGroup的子類Layout來說,設置Orienatation,可用來決定子類的位置
FillModel,出現這種情況主要是默認情況,某些元素不能完全佔滿父區域的空間,這時除非子VIEW已經設置具體和DPI,否則話需要告訴父控件,你所選擇填充空間方式,如Fill-parent或者Wrap-content等。
Gravity,Gravity與Orientation是不同,Gravaity與Word文檔中左對齊,右對齊類似。缺省是左上對齊。
Weight,這個在兩個控制同時分配剩餘空間,需要設置layout-weight決定兩者誰的佔比。
【2】請求焦點,可以通過函數實現焦點轉換。不同的焦點可以實現不同的背景變換等功能。焦點在Android裏分爲幾種情況,一種是可以獲取焦點,另外一種是不能獲取焦點,第三種是可獲取焦點,但當前正取觸摸狀態下。
【3】設置事件監聽者,所有的View都會在本身發生變化將自身的信息廣播出去。比喻點擊、焦點失去得到等。通常一個事件來到,Android會將事件傳 遞到相應的View,然後View將事件傳遞到相應的Listeners。這時View需要獲取焦點,如果需要重新繪製View的話,需要調用 invalidate(0或者reqeustLayout重新繪製整個界面。
【4】設置顯示與隱藏,還可以對其內容設置scrolling。
2.1.1 View、Window、Activity、Dispay之間的關係
這些都是組成Android 系統顯示的關鍵元素。我們首先來了解Dispay。Dispay代表了硬件顯示屏幕信息。

image

通過這些函數可以瞭解一個屏幕的寬、高及分辨率還有是橫屏還堅屏等一些基本情況,透過這些函數,我們開發應用時可以方便的得到當前安裝我這個應用的屏幕的 大小,以便調整應用使用戶得到更好的用戶體驗。接下來我們看其它三者之間的關係,我想大家雖然看了前面的View的介紹和SDK中關係UI的基本介紹之後 還是對Android圖形窗口十分困惑,看API也是,有WindowMangaer接口和Window類,但是在說明文檔中,並未提到如何用這些。但實 際上這裏面要去看到Android核心,Android核心底層GDI是SKIA,同chrome是一樣的GDI,但是GUI是不一樣的。這裏面 Android實現的是C/S模式。如下圖所示

image

從上圖,我們可以理出大致的顯示過程如下:
【1】ActivityManagerService創建Activity線程,激活一個activity
【2】系統調用Instrumentation.newActivity創建一個activity
【3】Activity創建後,attach到一個新創建的phonewindow中。這樣Activity獲取一個唯一的WindowManager服務的實例
【4】Activity創建過程中使用setcontentView設置用用戶UI,這些VIEW被加入到PhoneWindow的ContentParent中。
【5】Activity線程繼續執行,當執行到Activity.makeVisible是將根view DecoView加入到WindowManger中,WindowManger實全會爲每個DecoView創建對應的ViewRoot
【6】每個ViewRoot擁有一個Surface,每個Surface將會調用底層庫創建圖形繪製的內存空間。這個底層庫就是SurfaceFlinger。SurfaceFlinger同時也負責將個View繪製的圖形合到一塊(按照Z軸)顯示到用戶屏幕。
【7】如果用戶直接在Canvas上繪製,實際上它直接操作Surface。但對每個View的變更,它是要通知到ViewRoot,然後 ViewRoot獲取Canvas。如果繪製完成,surfaceFlinger得到通知,合併Surface成一個Surface到設備屏幕。
從上面的圖形輸出過程分析,我們可以知道真正顯示圖形的實際上跟Activity沒有關係,完全由WindowManager來決定。 WindowManager是一個系統服務,因此可以直接調用這個服務來創建界面,並且更絕的是Dialog、Menu也是有WindowManager 來管理的。另外一個我們也可以看到,最底層都是Surface來,因此,常見開發遊戲的人都推薦你使用SurfaceView來創建界面。

作者“棕櫚燒酒”

 

sourceurl:http://www.2cto.com/kf/201109/104633.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章