建立檢視畫面類別

試用 Compose 方法
Jetpack Compose 是 Android 推薦的 UI 工具包。瞭解如何在 Compose 中處理版面配置。

設計完善的自訂檢視畫面,就像其他設計完善的類別一樣。這種程式庫可透過簡單的介面封裝一組特定功能、有效使用 CPU 和記憶體等。除了設計完善的類別外,自訂檢視區塊也必須執行以下操作:

  • 符合 Android 標準。
  • 提供可與 Android XML 版面配置搭配使用的自訂樣式屬性。
  • 傳送無障礙功能事件。
  • 與多個 Android 平台相容。

Android 架構提供一組基本類別和 XML 標記,協助您建立符合上述所有要求的檢視畫面。本課程說明如何使用 Android 架構建立檢視區塊類別的核心功能。

詳情請參閱自訂檢視畫面元件

將檢視畫面設為子類別

Android 架構中定義的所有檢視畫面類別會擴充 View。自訂檢視區塊也可以直接擴充 View,或擴充其中一個現有檢視區塊子類別 (例如 Button) 以節省時間。

為了讓 Android Studio 與檢視畫面互動,您至少必須提供採用 ContextAttributeSet 物件做為參數的建構函式。這個建構函式可讓版面配置編輯器建立及編輯檢視畫面的執行個體。

Kotlin

class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)

Java

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>

此程式碼宣告了兩個自訂屬性 showTextlabelPosition,這些屬性屬於名為 PieChart 的可設定實體。依照慣例,可設定實體的名稱與定義自訂檢視區塊的類別名稱相同。雖然您不一定要遵循此慣例,但許多知名的程式碼編輯器仍仰賴這個命名慣例來提供陳述式。

定義自訂屬性後,您就可以在版面配置 XML 檔案中使用這些屬性,就像內建屬性一樣。唯一的差別在於自訂屬性屬於不同的命名空間。它們屬於 http://schemas.android.com/apk/res/[your package name],而非 http://schemas.android.com/apk/res/android 命名空間。例如,以下說明如何使用為 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-auto">
 <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()。針對 res/ 目錄中的每個 <declare-styleable> 資源,產生的 R.java 會定義屬性 ID 陣列和一組常數,用於定義陣列中各個屬性的索引。您可以使用預先定義的常數,從 TypedArray 讀取屬性。PieChart 類別讀取其屬性的方式如下:

Kotlin

init {
    context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.PieChart,
            0, 0).apply {

        try {
            mShowText = getBoolean(R.styleable.PieChart_showText, false)
            textPos = getInteger(R.styleable.PieChart_labelPosition, 0)
        } finally {
            recycle()
        }
    }
}

Java

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);
       textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

請注意,TypedArray 物件是共用資源,使用後必須回收。

新增資源和事件

屬性是控制檢視畫面行為和外觀的強大方法,但只能在檢視畫面初始化時讀取。如要提供動態行為,請公開每個自訂屬性的屬性 getter 和 setter 配對。下列程式碼片段說明 PieChart 如何公開名為 showText 的屬性:

Kotlin

fun isShowText(): Boolean {
    return mShowText
}

fun setShowText(showText: Boolean) {
    mShowText = showText
    invalidate()
    requestLayout()
}

Java

public boolean isShowText() {
   return mShowText;
}

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

請注意,setShowText 會呼叫 invalidate()requestLayout()。這些呼叫至關重要,是為了確保檢視區塊能夠穩定執行。如果檢視畫面的屬性變更可能會改變外觀,您就必須將檢視畫面失效,讓系統知道必須重新繪製。同樣地,如果屬性的變更方式可能影響檢視畫面的大小或形狀,您就必須要求新的版面配置。忘記這些方法呼叫可能會導致難以找到的錯誤。

自訂檢視畫面也必須支援事件監聽器,以便傳達重要事件。舉例來說,PieChart 會公開名為 OnCurrentItemChanged 的自訂事件,通知事件監聽器使用者旋轉了圓餅圖,以專注於新的圓餅圖。

很容易忘記顯示屬性和事件,特別是當您是自訂檢視區塊的唯一使用者時。花時間仔細定義檢視表介面,即可降低日後的維護費用。建議您一律揭露會影響自訂檢視畫面可見外觀或行為的所有屬性。

採用無障礙設計

您的自訂檢視畫面必須支援各種使用者。包括身心障礙使用者無法觀看或使用觸控螢幕。如要支援身心障礙使用者,請執行下列操作:

  • 使用 android:contentDescription 屬性為輸入欄位加上標籤。
  • 在適當情況下呼叫 sendAccessibilityEvent() 傳送無障礙功能事件。
  • 支援替代控制器,例如 D-Pad 或軌跡球。

如要進一步瞭解如何建立無障礙檢視畫面,請參閱「 提高應用程式的無障礙程度」。