自訂視圖
Android架構雖然提供了許多與使用者互動,並且能夠展現各種資料的視圖,但是有的時候Android內建的基本視圖控制項並不能夠很好的滿足一些特殊的要求,這個時候我們就需要自訂視圖控制項
建立自訂視圖類
一個設計的很好的自訂視圖就像一個設計的很好的類一樣,它封裝了一組特定的、便於使用的方法,它高效合理的利用手機CPU和記憶體,除了需要是一個設計良好的類之外,一個自訂的視圖還應該滿足以下幾個條件:
1、符合Android平台標準 2、用Android XML layouts來提供自訂樣式化屬性 3、發送可訪問性的事件 4、要能夠相容多種Android版本平台
Android架構為我們提供了一套基礎的類和XML標籤來協助我們建立一個滿足以上要求的視圖類,現在我們就來學習下怎麼利用Android架構來實現一個視圖類的核心功能函數
如何建立一個自訂視圖類
在Android架構中所有的視圖類都是繼承自View類,我們的自訂視圖類也可以直接繼承View類,當然如果為了節省時間我們也可以繼承自一個已經實現好了的View的子類,例如Button類 為了讓我們的視圖能夠和Android Developers Tool進行互動,我們的自訂視圖類必須提供一個以Context和
AttributeSet類型為參數的建構函式,通過這個建構函式我們的視圖控制項就能夠讓布局編輯器通過資源檔來進行構造和設定樣式了,讓我們可以在Android提供的圖形編輯器中進行編輯
class PieChart extends View { public PieChart(Context ctx, AttributeSet attrs) { super(ctx, attrs); }}
定義自訂屬性
我們把一個內建的視圖添加進使用者介面,我們需要在一個XML元素檔案中指定它,通過元素屬性來控制它的顯示和行為,為了更好的實現自訂視圖,我們也需要通過XML來把它添加進使用者介面和定義它的樣式,為了滿足這個需求我們應該做到如下幾點
1、在資源元素
<declare-styleable>
中定義自訂屬性 2、在XML layout檔案中指定屬性的值 3、在運行時檢索屬性的值 4、在視圖中應用檢索到的屬性值
在
res/values/attrs.xml 使用
<declare-styleable> 元素定義自訂屬性
<resources>; <declare-styleable name="PieChart"> <attr name="showText" format="boolean" /> <attr name="labelPosition" format="enum"> <enum name="left" value="0"/> <enum name="right" value="1"/> </attr>
</declare-styleable>
</resources>
在XML layout中指定自訂屬性的值
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews"> <com.example.customviews.charting.PieChart custom:showText="true" custom:labelPosition="left" />
</LinearLayout>
在我們自訂的視圖控制項添加進layout中時,我們要指定類全名<packageName.className>,如果我們的視圖類是內部類的話那就是<packageName.outClassName$innerClassName>
使用自訂屬性
當你的視圖在XML layout中建立出來的時候,所有配置的屬性都是可以從資源檔中讀取出來的,並會把它們當做 AttributeSet 類型的參數傳遞到視圖的建構函式中,雖然可以直接從 AttributeSet 中讀取屬性的值,但這樣做有一些缺點: 1、沒有解決在資源檔中引用屬性值的問題 2、樣式還沒有被附加 我們可以通過
obtainStyledAttributes()
方法
來讀取屬性的值,當調用
obtainStyledAttributes()
方法時會有一個TypedArray
類型的傳回值,TypedArray 裡儲存的屬性值都是經過引用和附加過樣式
public PieChart(Context ctx, AttributeSet attrs) { super(ctx, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0); try { mShowText = a.getBoolean(R.styleable.PieChart_showText, false); mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0); } finally { a.recycle(); }}
暴露屬性和添加事件監聽 屬性是一個有力的手段用來控制視圖的外觀和行為,但是它們只有當視圖初始化完成後才能夠取得,為了提供一種動態手段,為每一個自訂的屬性提供setter和getter方法
public boolean isShowText() { return mShowText;}public void setShowText(boolean showText) { mShowText = showText; invalidate(); requestLayout();}
任何一個屬性值的改變,都有可能影響到視圖介面的外觀、呈現的資料,我們需要通過調用invalidate() 方法來通知系統重新繪製視圖介面,同樣地,屬性值的改變也有可能影響到視圖介面的大小和形狀,我們需要通過調用requestLayout()
來重建視圖介面的布局,這一點需謹記
我們還需要設定一些監聽器來監聽一些重要的事件,比如說使用者的觸屏事件...