TypedArray和obtainStyledAttributes使用

編寫Android自定義按鈕示例基礎上,如果要指定字體大小產生這樣的效果:

image

其實是不需要自定義變量的,可以直接使用TextView的配置屬性:

<com.easymorse.textbutton.TextButton 
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    android:layout_weight="1" android:text="電影" 
    android:gravity="center_vertical|center_horizontal" 
    android:background="@drawable/button" android:focusable="true" 
    android:clickable="true" android:textSize="22sp" />

在這裏字體大小使用了sp,這裏要說一下sp與dp(dip)的區別,dip是:

dp Density-independent Pixels – an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Note: The compiler accepts both "dip" and "dp", though "dp" is more consistent with "sp".

不過,要是和字體有關,最好還是用sp,和dp類似,但更適合字體大小:

sp Scale-independent Pixels – this is like the dp unit, but it is also scaled by the user’s font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and user’s preference.

這裏爲了演示使用自定義變量,字體大小改用自定義的屬性。

首先要創建變量,創建了個values/attrs.xml文件,文件名任意,但是要在values目錄下:

<?xml version="1.0" encoding="utf-8"?>   
<resources>   
    <declare-styleable name="button">   
        <attr name="textSize" format="dimension" />   
    </declare-styleable>   
</resources>

根標籤要是resources,定義的變量要有個名字,declare-styleable name="button">,這裏定義名稱爲button。在這個名稱裏,可以有多個自定義屬性。定義了個名爲textSize的屬性,格式是dimension,這個format指定了textSize屬性的類型,只能用於定義字體大小。

在佈局文件中通過自定義屬性賦值:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:myapp="http://schemas.android.com/apk/res/com.easymorse.textbutton" 
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="fill_parent" android:background="@drawable/background_color"> 
    <LinearLayout android:layout_width="fill_parent" 
        android:layout_height="10dip" /> 
    <LinearLayout android:layout_width="fill_parent" 
        android:layout_height="40dip"> 
        <com.easymorse.textbutton.TextButton 
            android:layout_width="fill_parent" android:layout_height="fill_parent" 
            android:layout_weight="1" android:text="電影" 
            android:gravity="center_vertical|center_horizontal" 
            android:background="@drawable/button" android:focusable="true" 
            android:clickable="true" myapp:textSize="20sp" />

 

這裏在根標籤中增加了:

xmlns:myapp=http://schemas.android.com/apk/res/com.easymorse.textbutton

聲明瞭myapp這個名字空間,myapp是任意的名稱,自己可以隨便起名,後面的:

http://schemas.android.com/apk/res/

是固定的。再後面接的是應用的包名。

在下面自定義按鈕中的:myapp:textSize,就是使用<attr name="textSize"這個變量了,給變量賦值。

還需要一個過程,就是在程序中獲取到這個賦值:

public TextButton(final Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
    TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.button); 
    this.setTextSize(typedArray.getDimension(R.styleable.button_textSize, 15)); 
    typedArray.recycle();

 

其中,TypedArray實例是個屬性的容器,context.obtainStyledAttributes()方法返回得到。AttributeSet是節點的屬性集合,在本例中是<com.easymorse.textbutton.TextButton節點中的屬性集合。

這句話:

typedArray.getDimension(R.styleable.button_textSize, 
                15)

將獲取自定義textSize的值,如果沒有,則使用默認的值,15。

最後別忘記調用:

typedArray.recycle();

作用是:

Give back a previously retrieved StyledAttributes, for later re-use.

這裏的自定義屬性的format,可以有很多種:

  • reference
  • string
  • color
  • dimension
  • boolean
  • integer
  • float
  • fraction
  • enum
  • flag
發佈了19 篇原創文章 · 獲贊 5 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章