編輯:關於Android編程
在上一篇《Android開發技巧——自定義控件之自定義屬性》中,我講到了如何定義屬性以及在自定義控件中獲取這些屬性的值,也提到了關於這些屬性除了可以在布局文件中指定之外,也可以在主題中指定。接下來將分享我所了解的關於在主題中指定屬性值的兩種方式。
我們在開發過程中,雖然關於自定義控件學會了如何在布局文件中指定它的值,以應對不同的需求。但有時還會遇到這樣一種情況:我們希望對某個控件的屬性,能夠做一個全局的配置,這樣我在本項目中使用它的時候,都是同樣的表現,而不需要每個布局文件都復制一次屬性的值,而在另一個項目中,我們可以進行另一個全局的配置。
在上一篇中,我們講到了自定義屬性,如下所示:
其中format
定義了這個屬性的格式,它支持以下這些方式:
boolean
布爾值 color
顏色 dimension
尺寸 enum
枚舉 flag
位或運算 float
浮點值 fraction
百分數 integer
整型值 string
字符串 reference
引用某一資源ID
在定義格式時,還可以指定多種格式。比如
而這裡要說的就是reference
,引用某一資源ID。
我們可以定義一個屬性,格式為reference
,然後在theme
中配置它的值為某個style
,這樣我們就可以讀取到這個style
的屬性。這是我們對這個實現過程的思考。
下面以我以前寫的一個項目IconTabPageIndicator為例,全部代碼見其develop分支。這是一個底部菜單指示器,其中每個tab(繼承自TextView)的具體表現我們都希望能夠在style中定義。所以首先我們先定義一個屬性,用於指定這個tab的style:
下面分別說明對這個屬性的兩種使用方式。
重寫構造方法。在本例子中,我們的TabView是通過在java代碼中自己new出來的,調用的是構造方法TabView(Context context)
,所以我們需要重寫這個構造方法,在這個構造方法中調用this(context, null, R.attr.tabView)
,第三個參數傳入的是R.attr.tabView,即我們定義的style屬性。
public TabView(Context context) {
this(context, null, R.attr.tabView);
}
然後我們重寫所調用的這個帶defStyle
參數的構造方法,因為另外一個構造方法TextView(Context context, AttributeSet attrs)
也是調用了它:
public TabView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
TypedArray a = context.obtainStyledAttributes(attr, R.styleable.TabView, defStyle, 0);
iconWidth = a.getDimensionPixelSize(R.styleable.TabView_iconWidth, 0);
iconHeight = a.getDimensionPixelSize(R.styleable.TabView_iconHeight, 0);
a.recycle();
}
在構造方法中,首先第一行是調用父構造方法。接下來,我們就需要獲取我們自定義的其他屬性了,比如在這個例子中的圖標寬高,獲取時調用的方法與昨天所使用的有點不同 ,我們調用的是
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
,第三個參數是我們定義的style屬性,第四個參數則是style資源。在確定一個屬性最終的值的時候,優先級順序是這樣的:
style=@style/xxxx
)指定的資源獲取 如果找不到,則去defStyleAttr
以及defStyleRes
中的默認style中獲取。 最後去找的是當前theme
下的基礎值。
所以在上面的方法中,我們也可以給第四個參數傳一個我們默認的style(R.style.xxx),當使用者沒有在第三個屬性所指定的style中聲明一些屬性時,就會使用我們第四個參數中的style裡的屬性。
在調用obtainStyledAttributes
方法獲取到屬性之後,後面如何使用則可參考前一篇博客,或本項目。
理論上,其他人使用的時候,只要寫一個style,然後在他的應用的主題中指定,就可以了。但是通常我們會需要指定許多屬性的值,而這些屬性的值大部分情況下都是通用的。所以我們首先應提供一個良好的style,如下:
在這個style中,我定義了tab文字居中,背景色,字體大小顏色,邊距等。在不重寫其中的屬性的情況下,就能提供一個外觀良好的效果。
然後寫個theme
,在其中指定這個style,算是作為一個給其他開發者學習的示例:
這裡的tabView就是我們所定義的style屬性,也是我們在構造方法中指定的R.attr.tabView
。
如果庫的使用者需求對這style進行修改,只需要寫一個style,繼承自我們的TabView
style,重寫裡面的屬性值即可:
當然,還有最重要的一步:必須在自己的項目的主題中指定:
此例子的完整項目請參考Github項目IconTabPageIndicator
我們定義的style屬性,除了通過Java代碼來獲取使用之外,也可以直接通過布局文件來使用。需要使用到的是style
屬性。
我們對一個控件的style
屬性,通常的寫法都是:style=@style/xxxxx
,或者是指定android系統中的屬性:style=@android:style/xxxx
,除此之外,我們也可以用來指定我們所定義的style屬性。
我另一個練習的項目ActionSheet就是使用了這種方式。完整代碼請參見github上該項目地址,這裡僅摘取部分相關的代碼。
ActionSheet是我寫的一個和qq菜單有點像的菜單,我希望菜單的每一項都是可以配置的。由於菜單是通過Dialog來加載,而Dialog是在Java代碼中new出來,所以不能通過在xml中定義各個屬性來完成菜單外觀的配置,因此采用了這種方式。
首先同樣是定義一些屬性,和上面的一樣:
這裡表示的是菜單列表的屬性,取消按鈕的樣式,以及每一項菜單的樣式。然後在我們的菜單布局文件中,除了不允許配置的屬性我們進行了聲明之外,其他的都是用style
屬性來指定,寫法是style=?attr/你所定義的屬性名
,如下:
同樣在我們的style.xml文件中,需要定義這幾個style:
下面代碼略...
而庫的使用者,在使用的時候,也需要指定這幾個屬性值:
本篇到此結束,相關項目如下:
IconPageIndicator 開發分支,學習自JakeWharton大神的ViewPagerIndicator ActionSheet,學習自哪個項目我也忘了。
刪除選中的短信:我們刪除短信其實很簡單,但是我們要實現一個對話框去顯示,還需要一個對話框的進度條。刪除短信操作就是操作數據庫就行了。使用內容解析者去操作,但是我們要去看看
--------------------------------------廣播機制簡介-----------------------------------------
說明本文可能需要一些基礎知識點,如Canvas,Paint,Path,Rect等類的基本使用,建議不熟悉的同學可以學習GcsSloop安卓自定義View教程目錄,會幫助很
實現ActionAction是struts2應用的核心,開發中需要大量的Action類,並在struts.xml中配置Action。Action中包含了對用戶請求的處理邏