建立檢視畫面類別

嘗試 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 或軌跡球。

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