建立自定義view(翻譯 androidtraining)

 

建立自定義view

一個設計良好的的自定義view應該是一個設計良好的class,它包含了不少實用的功能,讓人們更加容易使用接口。它充分利用GPU與內存的性能等等。 另外做爲一個設計良好的類,一個自定義view還應該有如下特性:html

  • 聽從android標準java

  • 提供能夠在layout中使用的自定義屬性android

  • 兼顧各類人士需求(好比視力,聽力)web

  • 兼容各類android平臺版本數組

android的sdk提供了一系列的基礎的類和xml的標記來幫助你建立一個知足你需求的自定義view。本節課將討論如何利用android的framwork來建立一個有基本核心功能的自定義view。app

繼承一個view


android系統framwork層的view都是繼承自View這個基類。你的自定義view也能夠直接繼承自View,或者你爲了節省時間能夠繼承一個已經存在的子類,好比Button。編輯器

爲了讓Android Developer Tools 能和你的自定義view交互,你必須最少提供一個接受Context和AttributeSet爲參數的構造函數。經過這個構造函數,layout編輯器能夠建立和編輯你的自定義view的實例。(也就是能夠在未運行的時候,展現出界面)ide

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

定義自定義的屬性

爲了向你的界面中添加一個內建的view,你須要在xml元素裏面指定,而後經過元素的屬性控制它的顯示和行爲。爲了作到這一點,你必須:函數

  • <declare-styleable>資源屬性下爲你的自定義view定義屬性性能

  • 在xml layout中指定屬性的值

  • 在運行的時候,接受屬性的值

  • 將接受的值應用到你的view中去

這一節討論瞭如何定義自定義的屬性與指定他們的值。下一節將處理在運行時接收與應用屬性的值。

爲了定義自定義屬性,添加<declare-styleable>資源到你的工程中。一般咱們會將這些資源放到res/values/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>

上面的代碼聲明瞭兩個自定義屬性,showtextlablePosition,這兩個屬性屬於styleable 實體,命名爲PieChart,styleable實體的命名一般爲了方便,和你的自定義view的名字同樣。儘管這不是一個嚴格的規定,可是不少很是流行的開源代碼的做者也是聽從這個原則。

一旦你定義了自定義屬性,你就能夠像內置的android屬性那樣來運用你的屬性。惟一的不一樣就是你的自定義屬性是屬於一個不一樣的命名空間的。他們不是屬於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>

爲了不重複這麼長的命名空間,上面的例子使用了一個xmlns指示符。這個指示符把custom這個名字賦值給了http://schemas.android.com/apk/res-auto這個命名空間。 你能夠選擇任何的同名簡化單詞來替代你的命名空間。

Note:若是你沒有使用gradle來構建你的系統,你的xlmns URI不能包含 res-auto 。這個URI比較包含完整的你的項目的名字。這個例子中,若是不是grale構建的話,URI應該爲http://schemas.android.com/apk/res/com.example.customviews

請注意你在xml中指定的你的自定義view的名字。這個名字必須是這個類完整的類路徑。若是你的自定義view是一個inner class,你必須講outer class的名字也加上。例如,這個PieChart類若是有一個inner class 叫PieView.爲了使用這個自定義view的屬性,你應該這樣寫你的tag com.example.customviews.charting.PieChart$PieView

屬性值的應用

當一個view從xml layout中建立出來後,全部的在xml tag中的屬性就會從resourse bundle中讀取出來而且傳遞給view的構造函數的參數AttributeSet.儘管咱們能夠直接從AttributeSet中讀取屬性值,可是這樣作有一些缺點。

  • 資源的引用的屬性值沒有被分解出來

  • Styles沒有被應用到屬性值上

因而,咱們把AttrbuteSet傳遞給obtainStyledAttributes()這個函數。這個函數會返回一個TypedArray,這個一系列的值,通過了解引用,同時將主題樣式應用到值上。

Android的資源編譯器在你調用obtainStyledAttributes()以前,作了不少工做。遍歷res目錄中<declare-styleable>資源的時候,生成了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對象是一個共享的資源,因此每次使用完畢後,請及時調用recycle方法。

添加類屬性與事件

xml的屬性是一個很強大的控制view顯示與行爲的方式,可是它們卻只能在view初始化的時候來讀取。爲了提供動態的行爲,咱們能夠爲每個xml屬性提供get與set方法。下面代碼片斷展現瞭如何向外部提供一個get與set接口:

public boolean isShowText() {
   return mShowText;
}

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

注意下,setShowText方法調用了invalidate()與requestLayout().這些調用很重要,是用來保證view的行爲是可靠的。當你修改了一些可能影響view顯示的屬性時,你必須invalidate你的view,這樣系統就能夠知道這個view須要從新繪製。一樣的,當你修改了一些影響view大小與形狀的屬性時,你必須調用requestLayout。忘記調用這個函數,可能到致使不少難以發現的bug。

自定義view也應該支持一些事件的監聽。例如,PieChart向外提供一個叫作 OnCurrentItemChanged方法,來通知監聽者用戶已經旋轉了pie chart。

咱們很容易就忘記向外提供屬性與事件監聽,尤爲是當這個自定義view只有咱們一我的使用的時候。花一些時間來定義這些view的接口,這樣能夠節省之後維護的成本花費。一個好的作法就是,將全部影響顯示與行爲的屬性都向外提供接口。

定義可接受性

你的自定義view應該儘量支持更多的用戶。包括視力,或者行動不方便的人士。爲了支持這些人,你應該:

  • 在你的輸入性的控件上面使用 android:contentDescription這個屬性

  • 在合適的時間經過調用sendAccessiblityEvent發送兼容性事件

  • 支持交叉輸入控制,好比軌跡球,D-pad

更多的關於建立兼容view的知識,請查看 Making Application Accessible

相關文章
相關標籤/搜索