1. 程式人生 > >Android自定義屬性及xmlns解析

Android自定義屬性及xmlns解析

寫在前面

halo,大家好~又到了每週一次的分享時間(放屁!),每天從出門到上班大約有四十多分鐘的公交,也利用這段時間刷刷別人的技術部落格,成長了很多,這周重新溫習了一下Android自定義View和屬性,在這個過程中,對下列xml佈局中的語法產生了好奇:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
>

xmlns幾乎在每一個xml檔案最外層控制元件都有,但是它有什麼作用呢?於是乎便有了想寫這篇部落格的衝動。
因此,本文的重點內容就是簡單闡述一下如何自定義View和它的屬性,並且再來講講xmlns的用途。

自定義View

眾所周知,View和ViewGroup承載著Android檢視的任務,並且ViewGroup繼承自View,Google為了降低開發者的入門門檻,提供了很多已經封裝好了的View控制元件,比如Button、TextView、ImageView等等,對於ViewGroup來說,也有LinearLayout、FrameLayout、RelativeLayout等能夠包含其他View的組控制元件。
無論哪一種控制元件,它都直接或者間接地繼承自View類,雖然Google所提供的控制元件非常豐富,但是在實際的專案中,往往需要自己去特定一些View控制元件,終歸有以下四種情況:
1. 繼承View
2. 繼承ViewGroup
3. 繼承已有的View
4. 繼承已有的ViewGroup

本文主要講述第一種情況,至於後面三種情況,就需要深入到View的繪製流程之中學習,萬變不離其宗。

onMeasure
onLayout
onDraw

這三座大山是View繪製的精髓,文章暫時不涉及View的繪製;如果只是建立一個普通的自定義View,則只用關心onDraw方法的重寫,還是直接依照步驟上程式碼看看吧:

建立MyView的建構函式:

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this
(context, attrs, 0); } public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0); s = typedArray.getString(R.styleable.MyView_Text); typedArray.recycle(); }

建構函式可以當成模板使用,其中看到有三個引數的建構函式的情況有些複雜,什麼是TypeArray?可以理解成xml佈局中屬性的集合,在自定義屬性中,也是通過這個物件來獲取我們需要的自定義值。

context.obtainStyledAttributes()  
方法接受四個引數,其中我們關心的是第二個引數,它是一個id值,  
構成方法是:  
R.styleable.XXX

建立自定義屬性類別

R.styleable.XXX就是我們需要自己定義的屬類別性,在res/values/中新建attrs.xml檔案,並新增以下程式碼:

<resources>
  <declare-styleable name="MyView">
       <attr name="Text" format="string"/>
       <attr name="TextColor" format="color"/>
       <attr name="TextDrawable" format="reference"/>
       <attr name="TextSize" format="integer"/>
       <attr name="TextAllow" format="boolean"/>
   </declare-styleable>
</resources>

標籤包裹自定義的屬性類別,也就是上文中XXX所需要替代的值,在該標籤下可以包含多個標籤值,每一個attr都代表能夠包含的屬性,而name表示的是xml中自定義的屬性名,format表示該屬性的取值型別,可以包含string、integer、boolean、color、refrence等,分別表示字串、int值、布林值、顏色id、物件引用(drawable等)。

xml中新增自定義屬性

我們在xml中為自定義View新增自定義屬性,可以如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activities.ViewActivity">

    <com.yourzeromax.test_new.views.MyView
        android:id="@+id/mv_test"
        android:layout_width="40dp"
        android:layout_height="40dp"
        app:Text="123" 
        app:TextAllow="true"
        app:TextColor="@color/colorAccent"
        app:TextSize="13"
        app:TextDrawable="@drawable/drable_list"/>

</LinearLayout>

我們再回來看一下View的建構函式中的程式碼:

     TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0);
      String  s = typedArray.getString(R.styleable.MyView_Text);
        typedArray.recycle();

其中s的值便是我們在xml中指定的字串值,在本例子中,s=”123”,這樣便完成了xml屬性到程式碼屬性的轉換,不信可以自己試試。

Tips:在使用完TyoedArray物件以後,一定要記得recycle()回收,避免記憶體洩漏的發生。

xmlns的作用

xml佈局中使用最多的是android:id、andorid:layout_width等形式,在我們自定義的xml中,添加了app:Text、app:TextAllow等這樣的寫法,其實冒號前面的單詞並不重要,重要的是後面引號中的內容,前面的單詞可以任意取名,我們在最開始指定了這樣一句程式碼:

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

包括系統自動為我們新增的這一句程式碼:

xmlns:android="http://schemas.android.com/apk/res/android"

正是這兩句程式碼的存在,才使得我們能夠使用android、app這樣的標籤,為什麼呢?

xmlns是xml namespace的縮寫形式,換言之,這條程式碼就是為我們指定了app或者android的名稱空間,一般情況下,我們引用“apk/res-auto”就讓app能夠訪問res下所有資源的能力,當然如果想讓其只能訪問某個res資源,只需要引用“包名/apk/res/具體屬性資料夾”即可。有了這些語句,就能夠讓我們使用已經制定好的屬性集,懂了吧?是不是特別簡單

xmlns:tools的用法

在佈局中,任意xml標籤下新增程式碼:

xmlns:tools="http://schemas.android.com/tools"

之後,我們便能使用android為我們提供的tools,先舉個開發過程中的案例:

有時候在佈局一個xml的過程中需要檢視某個TextView的文字效果,於是指定了android:Text =
“客戶們都是笨蛋”;這時,產品上線,結果忘了刪除這行程式碼,資料載入也沒有重新設定text內容。

這種場面是不是就很尷尬了?使用tools標籤就能夠避免這樣的尷尬,我們在xml佈局中加入tools:text=”客戶們都是笨蛋”,發現預覽中是這樣的:
這裡寫圖片描述
但實際上,如果執行的話,是看不到這條text的。
除此之外,tools:標籤幾乎支援所有android:的同名標籤,比如tools:src、tools:textSize等,可以自己進行探索。
總之,tools的作用就是能夠方便開發者在開發過程中提前預覽xml佈局而對之後的執行結果不產生影響,挺方便的一個工具。

歡迎關注我的部落格