Android 視圖(View)概述

視圖(View)概述

 


翻譯至 Android.View.View Class Overview,水平有限,敬請諒解。

 


        視圖(View)是一個矩形區域,它負責這個區域裏的繪製和事件處理。視圖類是Android用戶界面的基礎類之一。視圖組(ViewGroup)是視圖的子類,是一個容器,專門負責佈局。視圖組本身沒有可繪製的元素。
        開發用戶界面可以先閱讀開發者嚮導的用戶界面(User Interface)部分。
        該文章包含:
                聲明佈局
                創建菜單
                公用佈局對象
                AdapterView綁定數據
                處理UI事件
                應用風格(styles)或主題(themes)
                自定義組件
                Android怎樣繪製視圖

 

使用視圖
        一個窗口中的所有視圖是一個樹形結構。你可以通過代碼創建視圖,也可以通過XML佈局文件來創建。文本、圖像都是視圖的派生類。
        視圖和其子類具有如下共同特性:
         設置屬性,例如設置文本視圖的文本。不同的子類具有不同的屬性,這些屬性在設計時可以設定。
         設置焦點,爲了響應用戶輸入,Android框架會處理焦點的轉移。要把焦點轉移到特定視圖上,可以使用requestFocus()函數。
         設置監聽器(listener),視圖可以讓客戶端設置監聽器,特定事件發生時這些監聽器會收到通知。例如,視圖得到或失去焦點時,會收到關於焦點的通知。你可以使用setOnFocusChangeListener(View.OnFocusChangeListener)來註冊監聽器。例如,按鈕Button就有一個點擊事件的監聽器。
         設置可見性,用setVisibility(int)顯示和隱藏視圖。
        Android框架負責視圖的測量(measuring)、佈局(laying out)、繪製(drawing)。一般情況你不需要調用這些方法,除非你重載ViewGroup這樣的佈局類。

 

自定義視圖
        自定義視圖需要重載下列一些方法。
       

IDs
        視圖有整數ID,這些ID一般在XML佈局文件中分配。一般的樣式
        定義一個按鈕並分配一個唯一ID
         <Button id="@+id/my_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/my_button_text"/>
        onCreate函數創建視圖時,查找一個按鈕
                Button myButton = (Button) findViewById(R.id.my_button);
        視圖ID並不要求是全局唯一,不過爲了便於搜索最好在視圖樹的局部是唯一。


位置
        視圖在幾何上就是一個矩形,左上角的left和top座標定位,寬width和高height表示尺寸大小,單位是像素pixel。
        使用getLeft()和getTop()獲取左上角位置,這些位置都是相對於父視圖。
        此外還有幾個方便方法getRight()和getBottom()獲得右邊和底部位置。

尺寸,內間距padding,外間距margins
        視圖的尺寸用寬和高表示,一個視圖有兩對寬高值。
        第一對寬高值是測量值(measured width, measured height),測量值是子視圖相對父視圖的尺寸大小期望值。可以用getMeasuredWidth()和getMeasuredHeight()獲取。
        第二對寬高值是實際值,實際尺寸是視圖完成佈局後繪製時用到的值。
        測量尺寸大小時要計算內間距padding,內間距表示了視圖內各個子控件到父控件上下左右四條邊的間距。
        普通視圖不支持外間距,只有ViewGroup支持。詳見ViewGroup.MarginLayoutParams。


佈局Layout
        佈局分兩個階段(pass):測量階段(measure pass)和佈局階段(layout pass)。測量階段在measure(int, int)方法中實現,整個過程就是從上至下的視圖樹遍歷。在這個遞歸過程,每個視圖都提供尺寸大小描述。測量階段的最後,每個視圖都保存了自己的測量結果。佈局階段在layout(int, int, int, int)函數中實現,這也是一個從上至下的過程。在佈局階段,每個父視圖使用測量階段的估算值爲子視圖安排位置和大小。
        當視圖的measure()方法返回後,它和它的子控件的測量值都已經計算出來了。子控件的測量值都要考慮父視圖的區域限制,這就保證了在測試階段結束時,每個父視圖能接受其所有子控件的測量結果。子控件的measure()方法可能被多次調用。例如,包含了尺寸不確定的子控件,父控件會對每個子控件調用一次measure()方法,然後再對尺寸明確的子控件調用measure()方法,這樣作是爲了保證沒有確切尺寸的子控件不至於太大或太小。
        測量階段會用到兩個類:View.MeasureSpec和LayoutParams。視圖使用View.MeasureSpec類來表明自己所期望的位置和測量

方式,LayoutParams則是來表明自己期待的大小。
        它們都可以使用下面的值:
                確切的數值
                MATCH_PARENT,在父控件裏儘可能的大(除去內間距padding值)。
                WRAP_CONTENT,儘可能的小,只要能容納自己的子控件即可(加上內間距padding值)。
        LayoutParams有一些派生類,會被視圖組ViewGroup用到。例如,AbsoluteLayout包含了X和Y值,用來描述佈局時的絕對位置。
        MeasureSpecs在父視圖向子控件詢問佈局期望時會被用到。它有三種模式:
        UNSPECIFIED,未指定,父控件向子控件詢問佈局期望值。例如,線性佈局類LinearLayout想知道子控件在寬爲240的時候高的期望值,便可以調用子控件的measure()方法,並在傳遞參數中指定高爲UNSPECIFIED,寬爲確定值240像素。
        EXACTLY,確定值,父控件指定子控件的尺寸,並要求該子控件的子控件也必須適應這個尺寸。
        AT_MOST,最大值,父控件指定子控件的最大尺寸,並要求該子控件的子控件也必須適應這個尺寸。
        當視圖想父控件再次對自己執行佈局操作時,可以調用requestLayout(),一般在視圖的尺寸發生改變時會有這種需求。

繪製Drawing
        繪製按照視圖樹的順序執行。視圖繪製時會先繪製子控件。如果視圖的背景可見,視圖會在調用onDraw函數之前繪製背景。
        強制重繪,可以使用invalidate()。

事件處理和線程
        事件的基本流程如下:
                1。事件分配給相應視圖,視圖處理它,並通知相關監聽器。
                2。操作過程中如果發生視圖的尺寸變化,則該視圖用調用requestLayout()方法,向父控件請求再次佈局。
                3。操作過程中如果發生視圖的外觀變化,則該視圖用調用invalidate()方法,請求重繪。
                4。如果requestLayout()或invalidate()有一個被調用,框架會對視圖樹進行相關的測量、佈局和繪製。
        注意,視圖樹是單線程操作,直接調用其它視圖的方法必須要在UI線程裏。跨線程的操作必須使用句柄Handler。


焦點處理
        框架處理焦點的轉移,來相應用戶輸入。isFocusable()函數表示視圖是否能接受焦點。setFocusable(boolean)函數可以改變視圖能否接受焦點。觸摸屏模式(Touch Mode)的相關函數是isFocusableInTouchMode()和setFocusableInTouchMode(boolean)。
        焦點轉移按照就近算法。按哪個方向就近可以在XML佈局文件中配置。
         nextFocusDown
         nextFocusLeft
         nextFocusRight
         nextFocusUp
        視圖請求焦點可以使用requestFocus()。


觸摸屏模式Touch Mode
        當用戶使用方向鍵盤(D-pad)操作時,當前控件需要聚焦高亮來提示用戶。但是對於觸摸屏,就不再需要這種高亮了。我們管這種模式叫觸摸屏模式。
        用戶一接觸觸摸屏設備就進入觸摸屏模式。從此,只有isFocusableInTouchMode()函數返回true的視圖才能聚焦高亮,例如文本框。而按鈕就不需要在觸摸屏模式下高亮了。
        用戶一接觸方向鍵,界面就退出觸摸屏模式,並找到當前哪個視圖需要聚焦高亮,以便用戶在鍵盤模式下也能確認正在操作的控件。
        觸摸屏模式是全局性的,跨Activity的。isInTouchMode()函數可以獲得是否在觸摸屏模式下。


滾動Scrolling
        視圖本身支持滾動,包括XY的偏移位置和滾動條的繪製。


標籤Tag
        標籤用於儲藏對象


動畫Animation
        視圖可以附加Animation對象,設置動畫setAnimation(Animation),啓動動畫startAnimation(Animation)。Animation可以按時間軸改變視圖的位移、縮放大小、旋轉角度和透明度,來製造動畫效果。Animation的效果是包括了該視圖的子視圖。動畫啓動後,框架就負責重繪該視圖。

發佈了26 篇原創文章 · 獲贊 4 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章