Android UI : XML & 反射

devliu發表於2017-05-04

前言

對於 Android 程式設計師來說, 佈局 XML 檔案我們幾乎每天都會寫好幾個, 而恰恰是很多每天都會用到的東西, 往往因為「習慣了」而忽略對其原理的探究.

[toc]

對XML檔案的認知

反射 & 配置檔案

定義格式 & 疑問

大家應該都有過這樣的需求, 在程式碼中根據實時的資料, 通過程式碼動態控制 UI.
而在使用的過程中就會明顯的感覺到 xml 定義 佈局的便利性. 而在使用程式碼控制的過程中, 發現 xml 中出現的屬性在程式碼控制時都有相應的 get/set方法. 這不由得使我聯想到 javaWeb spring 框架的 spring Bean.

而通過猜想和搜尋相關資料驗證, 內部確實是通過反射機制實現的.

使用反射的目的

javaWeb 開發, SSH 框架中的 spring 強大的 IOC 容器, 通過註解, XML配置和反射, 實現了控制反轉和依賴注入.

使用spring框架後, 基本見不到new物件的情況, 而是使用配置檔案的形式例項化物件.

而反射給我印象深刻的一句話就是:

當你的程式編寫完成, 並編譯成為可以正常執行的軟體後, 如果之後要實現功能的更改, 是否只能重新編輯原始碼並再次編譯?

目的在於方便重用和減低耦合度, 減少專案變動所牽連的元件. 這就需要使用配置檔案, 而最常見的配置檔案格式就是 xml.

低耦合舉例: 業務邏輯程式碼中不能夠出現和JDBC有關的程式碼, 日後業務擴充套件, 更換資料庫系統,業務程式碼不會受到影響, 只需要在配置檔案中更換反射類名即可更換JDBC實現類.

Android UI XML

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <Button
        android:id="@+id/btn_demo"
        android:onClick="setAnimation"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="動畫集合" />

</LinearLayout>

NameSpace

xmlns :意為xml名稱空間(name space).

  • xmlns:android=”http://schemas.android.com/apk/res/android”

  • xmlns:tools=”http://schemas.android.com/tools”

  • xmlns:app=”http://schemas.android.com/apk/res-auto”

相當於java檔案中的「import」, 名稱空間主要是因為, 不可避免的類名, 屬性名重複, 通過新增字首以分類, 保證唯一性.

之後在下方使用android:text時相當於寫下了http://schemas.android.com/apk/res/android:text

tools xlmns

tools:context=”com.example.test.MainActivity”

標示上下文, 也就是相關聯的Activity.java檔案. 因為佈局顯示可以在, AndroidManifest.xml,Activity.java,res/layout, 多處同時定義, 使用此屬性關聯,以達到在佈局視覺化介面, 所見即所得的效果.

tools:text

我們經常遇到 textView 在程式碼中動態定義時, 視覺化預覽介面無內容, 不方便預覽. 此時使用android:text=””臨時預覽有可能忘記刪除. 這時就用到了 tools: 名稱空間.
Tools:text=”” 會在視覺化介面顯示, 而不會在實際執行時生效.

在顯示佈局時, 框架會讀取指定目錄下的xml文字, 通過遞迴遍歷整個佈局樹形巢狀結構. 再經過反射形成記憶體中的物件. (根元素-子元素結構 類比 資料夾-檔案結構).

<LinearLayout/>或者<LinearLayout></LinearLayout>為一個元素,兩種格式以其中是否有子元素來區分.上方 xml 示例中 : 此時 LinearLayout 下有子元素 Button

LinearLayout 為元素名,對應經過反射後生成的類名.
其後以鍵值對形式定義.是在初始化LinearLayout物件的成員屬性, 相當於構造器.

app xmlns

用於自定義控制元件中的自定義屬性名稱空間

總結

通過以上的探究過程, 也就解釋了, 為什麼控制元件存在兩種使用方式, 而且程式碼中呼叫的方法名和屬性名與XML檔案中極其相似的現象. 而遵從”低耦合”的軟體專案設計思想, 同時抽取元件定義方便重用和更改, Google官方推薦在XML中定義元件也是理所應當的.

相關文章