Android開發技巧——自訂控制項之使用style

來源:互聯網
上載者:User

Android開發技巧——自訂控制項之使用style
Android開發技巧——自訂控制項之使用style回顧

在上一篇《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:

    

下面分別說明對這個屬性的兩種使用方式。

在Java代碼中擷取

重寫構造方法。在本例子中,我們的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資源。在確定一個屬性最終的值的時候,優先順序順序是這樣的:

首先擷取給定的AttributeSet中的屬性值 如果找不到,則去AttributeSet中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,繼承自我們的TabViewstyle,重寫裡面的屬性值即可:

當然,還有最重要的一步:必須在自己的項目的主題中指定

此例子的完整項目請參考Github項目IconTabPageIndicator

在布局檔案中指定style屬性

我們定義的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,學習自哪個項目我也忘了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.