Android 用戶界面---定制組件(Custom Components)

fmms 12年前發布 | 29K 次閱讀 Android Android開發 移動開發

基于布局類ViewViewGroup的基本功能,Android為創建自己的UI界面提供了先進和強大的定制化模式。首先,平臺包含了各種預置的ViewViewGroup子類---Widgetlayout,可以使用它們來構造自己的UI界面。

部分的可以利用的widget包括:ButtonTextViewEditTextListViewCheckBoxRadioButtonGallerySpinner、以及比較特殊用途的AutoCompleteTextViewImageSwitcherTextSwitcher

其中可利用的布局是:LinearLayoutFrameLayoutRelativeLayout以及其他的布局。更多的例子請看“共通布局對象”。http://developer.android.com/guide/topics/ui/layout-objects.html

如果遇到了沒有預置的widgetlayout的需求,可以創建自己的View子類。如果只需要對既存的widgetlayout進行小的調整,那么只需簡單的繼承widgetlayout,并且重寫它們的方法。

創建自己的View子類,以便能夠精準的控制屏幕元素的外觀和功能。以下是用定制View對象來實現這種控制想法的一些例子:

1.  創建一個完全的定制化渲染的View類型,如用類似模擬電子控制的2D圖形來渲染的音量控制按鈕。

2.  把一組View組件組合成一個新的單一組件,制作一些像ComboBox(一個下拉列表和文本輸入域的組合)、雙面板選擇器(左右兩個列表面板,右邊的列表面板中的項目與左邊列表面板中的一個項目相關聯)等組件。

3.  重寫一個EditText組件在屏幕上的渲染的方法。

4.  捕獲一些像按鍵一樣的事件,并在某些定制的方法中處理它們(如游戲)。

基本方法

以下是創建自定義View組件需要要了解基本概要:

1.  自定義的View類要繼承一個既存的View類或其子類;

2.  在子類重寫父類的一些方法。要覆寫的父類方法是用‘on’開頭的,例如,onDraw()onMeasure()onKeyDown()等,這有點類似于重寫ActivityListActivity的生存周期回調的on…事件。

3.  使用新的擴展類,一旦完成,新擴展的類就能被用于替換基本的View對象。

提示:擴展類能夠作為使用它們的Acticity的內部類來定義。這樣對控制對它們的訪問是有益的,當然可以創建一個新的公共的View類,這樣就可以在應用程序范圍內來使用。

完全定制化的組件

完全定制化的組件能夠用于創建你所期望的顯示效果的圖形化組件。可以是看上去像舊的模擬儀表的圖形化VU儀表,或者是一個長的歌詞視圖,有一個跳動的球沿著歌詞移動,以便跟著這卡拉OK機歌唱,這兩種情況,無論如何組織內置的組件都無法滿足要求。

幸運的是,能夠使用任意自己喜歡的方法來創建組件的外觀和行為,唯一的限制就是你的想象力、屏幕的尺寸和可利用的處理能力(因為應用程序最終可能運行在比桌面工作站處理能力要弱的設備上)。

以下是創建完全定制組件的步驟:

1.  毋庸置疑,能夠擴展的最通用的視圖是View類,因此通常是繼承這個View類來創建自己的新的組件;

2.  提供一個能夠從XML中獲取屬性和參數的構造器,并且也能夠使用自己屬性和參數(如VU儀表的顏色和范圍,指針的寬度和阻尼等);

3.  創建組件中可能的事件監聽器、屬性訪問器和修飾符以及盡可能準確的行為等;

4.  覆寫onMeasure()回調方法,如果想要組件顯示一些東西,也要覆寫onDraw()回調。雖然它們都有默認的行為,onDraw()回調默認什么也不做,onMeasure()方法默認的要設置組件的尺寸為100x100

5.  覆寫其他的需要on…方法。

擴展onDraw()onMeasure()

onDraw()方法會把能夠實現的任何想要的東西放到一個Canvas對象上,如2D圖形、標準或定制的組件、樣式化的文本、或其他任何能夠想到的東西。

注意:View類不能使用3D圖形。如果要使用3D圖形,必須繼承SurfaceView類,而不是View類,并且要在一個獨立的線程中描畫。

onMeasure()方法有點復雜,它是組件和它的容器之間的渲染約束的關鍵部分。覆寫onMeasure(),以便準確高效的報告組件被包含部分的尺寸。由于來自父容器限制的要求,使得尺寸的測量有些復雜,并且組件的尺寸一旦被計算完成,就要調用setMeasureDimension()方法來保存測量的寬度和高度。如果在onMeasure()方法中調用setMeasureDimension()方法失敗,這個結果在測量時將是一個異常的值。

在上層看,實現onMeasure()方法的步驟如下:

1.  要用父容器的寬度和高度的計量規格來調用被覆寫的onMensure()方法(widthMeasureSpecheightMeasureSpec參數都是代表了尺寸的整數),這兩個參數應該作為生成組件的寬度和高度的約束要求。對于這些規格約束類型的完整說明可以在View類說明的View.onMeasureint,int)方法中找到。

2.  組件的onMeasure()方法應該計算用于渲染組件所需的尺寸(寬度和高度)。組件應該盡量保留在被傳入的規格范圍內,盡管它能夠選擇超出規格范圍(在這種情況下,父容器能夠選擇做的事情包括:裁剪、滾動、拋出異常、或者要求onMeasure()方法用不同的尺寸規格再試)。

3.  一旦組件的寬度和高度被計算完成,就必須調用setMeasuredDimension(int width, int height)方法來保存計算結果。不這樣做就會拋出一個異常。

下表是framework調用View類的其他標準方法:

分類

方法

說明

Creation

Constructors

構造器的調用有兩種類型:1.在代碼中創建View對象;2.用布局文件填充View對象。第二種類型應該解析和應用布局文件中的任何屬性定義。

onFinishInflate()

View對象和它的所有子對象都用XML填充完之后,調用這個方法。

Layout

onMeasure(int, int)

調用這個方法決定View對象及其所有子對象的尺寸要求。

onLayout(boolean,int,int,int,int)

View對象給它的所有子對象分配尺寸和位置時,調用這個方法。

onSizeChanged(int,int,int,int)

View對象的尺寸發生改變時,調用這個方法。

Drawing

onDraw(Canvas)

View對象渲染它的內容時,調用這個方法。

Event

onKeyDown(int,KeyEvent)

當一個鍵的按下事件發生時,調用這個方法

onKeyUp(int,KeyEvent)

當一個鍵彈起事件發生時,調用這個方法

onTrackballEvent(MotionEvent)

當鼠標軌跡球滾動事件發生時,調用這個方法。

onTouchEvent(MotionEvent)

當觸屏事件發生時,調用這個方法。

Focus

onFocusChanged(boolean,int,Rect)

View對象獲取或失去焦點時,調用這個方法。

onWindowFocusChanged(boolean)

當包含View對象的窗口獲得或失去焦點時,調用這個方法。

Attaching

onAttachedToWindow()

View對象被綁定到一個窗口時,調用這個方法。

onDetachedFromWindow()

View對象被從它的窗口中分離的時候,調用這個方法。

onWindowVisibilityChanged(int)

當包含View對象的窗口的可見性發生改變時,調用這個方法。

 

 

 

定制View的例子

API Demos中提供了一個定制的View對象的例子:CustomView。這個定制的View定義在LabelView類中。

LabelView示例展示了很多定制組件的不同特征:

1.  繼承View類的完全定制化的組件;

2.  參數化的帶有View填充參數(在XML中定義的參數)方式構造View對象。有一些填充參數使用通過這個View的父類傳遞過來的,還有一些用于labelView對象而定義的定制的屬性;

3.  你所期望看到的標準的公共類型的方法,如setText()setTextSize()setTextColor()等等;

4.  一個重寫的onMeasure()方法,它決定和設置了組件的渲染尺寸。(注意:在LabelView類中,實際的工作是由一個私有的measureWidth()方法來做的。)

5.  一個重寫的onDraw()方法,它在提供的Canvas上描畫標簽。

從這個示例的custom_view_1.xml中,能夠看到一些LabelView定制View的用法。實際上,可以看到android:命名空間參數和定制的app:命名空間的組合。這些app:參數是LabelView類所承認的并用于工作的一些定制化的屬性,并且這些參數在示例的R資源定義類的styleable內部類中被定義。

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!