【Interface&navigation】創建一個自定義視圖類(16)

精心設計的自定義視圖與其他精心設計的類非常相似。它使用易於使用的界面封裝了一組特定的功能,它高效地使用CPU和內存等等。不過,作爲一個設計良好的班級,自定義視圖應該:

符合Android標準
提供適用於Android XML佈局的自定義樣式屬性
發送無障礙事件
與多個Android平臺兼容。
Android框架提供了一組基本類和XML標籤,可幫助您創建滿足所有這些要求的視圖。本課討論如何使用Android框架來創建視圖類的核心功能。

除了本課,您還可以在“ 自定義組件”中找到其他相關信息。

子視圖


所有在Android框架中定義的視圖類都會擴展View。您的自定義視圖也可以View直接擴展,或者您可以通過擴展其中一個現有視圖子類來節省時間,例如Button。

要允許Android Studio與視圖進行交互,至少必須提供一個構造函數,該構造函數將 參數Context和AttributeSet對象作爲參數。該構造函數允許佈局編輯器創建和編輯視圖的實例。

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

定義自定義屬性


要View爲您的用戶界面添加內置內容,您需要在XML元素中指定它並使用元素屬性控制其外觀和行爲。寫得很好的自定義視圖也可以通過XML添加和設置樣式。要在自定義視圖中啓用此行爲,您必須:

在<declare-styleable> 資源元素中 定義視圖的自定義屬性
在XML佈局中指定屬性的值
在運行時檢索屬性值
將檢索到的屬性值應用於您的視圖
本節討論如何定義自定義屬性並指定它們的值。下一節將討論在運行時檢索和應用這些值。

要定義自定義屬性,請將<declare-styleable> 資源添加到您的項目中。習慣上把這些資源放到一個res/values/attrs.xml文件中。這是一個attrs.xml文件的例子:

<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>

此代碼聲明瞭兩個自定義屬性,showText並且labelPosition屬於名爲的可修改實體PieChart。按照慣例,可修改實體的名稱與定義自定義視圖的類的名稱相同。儘管遵循這個約定並不是嚴格必要的,但是許多流行的代碼編輯器依賴於這個命名約定來提供語句完成。

一旦定義了自定義屬性,就可以像使用內置屬性一樣在佈局XML文件中使用它們。唯一的區別是您的自定義屬性屬於不同的名稱空間。而是屬於的http://schemas.android.com/apk/res/android命名空間,他們屬於http://schemas.android.com/apk/res/[your package name]。例如,以下是如何使用爲以下內容定義的屬性 PieChart:

<?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>

爲了避免重複使用長名稱空間URI,示例使用了一個xmlns指令。該指令將別名分配custom給名稱空間http://schemas.android.com/apk/res/com.example.customviews。你可以選擇任何你想要的命名空間的別名。

注意將自定義視圖添加到佈局的XML標記的名稱。它是自定義視圖類的完全限定名稱。如果你的視圖類是一個內部類,你必須進一步用視圖外部類的名稱來限定它。進一步。例如, PieChart該類有一個名爲的內部類PieView。要使用這個類的自定義屬性,你可以使用標籤com.example.customviews.charting.PieChart$PieView。

應用自定義屬性


從XML佈局創建視圖時,將從資源束中讀取XML標記中的所有屬性,並以視圖的形式傳遞到視圖的構造函數中AttributeSet。儘管可以AttributeSet直接讀取值,但這樣做有一些缺點:

屬性值中的資源引用未解析
樣式不適用
相反,傳遞AttributeSet給obtainStyledAttributes()。該方法返回TypedArray已經解除引用和樣式化的值數組。

Android資源編譯器會爲您調用更多的工作obtainStyledAttributes() 。對於<declare-styleable> res目錄中的每個資源,生成的R.java都定義了一個屬性ID數組和一組定義數組中每個屬性索引的常量。您使用預定義的常量從中讀取屬性TypedArray。以下是PieChart該類如何讀取其屬性:

public PieChart(Context context, AttributeSet attrs) {
   super(context, 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();
   }
}

請注意,TypedArray對象是共享資源,使用後必須回收。

添加屬性和事件


屬性是控制視圖行爲和外觀的有效方式,但只有在初始化視圖時才能讀取它們。要提供動態行爲,請爲每個自定義屬性公開屬性getter和setter對。以下片段顯示瞭如何PieChart公開一個名爲的屬性showText:

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

注意setShowText呼叫invalidate() 和requestLayout()。這些調用對於確保視圖可靠運行至關重要。在對其屬性進行任何更改後,必須使該視圖無效,這可能會改變其外觀,以便系統知道它需要重繪。同樣,如果屬性更改可能會影響視圖的大小或形狀,則需要請求新佈局。忘記這些方法調用可能會導致難以發現的錯誤。

自定義視圖還應該支持事件監聽器來傳達重要事件。例如,PieChart 公開調用的自定義事件OnCurrentItemChanged以通知偵聽器用戶已將餅圖旋轉到專注於新餅圖片段。

很容易忘記公開屬性和事件,特別是當您是自定義視圖的唯一用戶時。花一些時間仔細確定您的視圖界面可以減少未來的維護成本。遵循的一條好規則是始終公開影響自定義視圖的可見外觀或行爲的任何屬性。

無障礙設計


您的自定義視圖應該支持最廣泛的用戶。這包括防止他們看到或使用觸摸屏的殘障用戶。爲了支持殘疾用戶,您應該:

使用android:contentDescription屬性 標記您的輸入字段
sendAccessibilityEvent()適當時通過呼叫發送輔助功能事件。
支持備用控制器,如D-pad和軌跡球
有關創建可訪問視圖的更多信息,請參閱 Android開發者指南中的 使應用程序可訪問

聯繫我

QQ:94297366
微信打賞:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公衆號推薦:

【Interface&navigation】創建一個自定義視圖類(16)

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