視頻鏈接:如何開發(fā)外觀樣式
實(shí)例代碼庫(kù):material-theme-builder
主題系統(tǒng)
- 有助于開發(fā)者創(chuàng)建更加靈活、可重復(fù)利用性更好的布局和樣式
- 提高代碼復(fù)用性與可維護(hù)性
- 現(xiàn)代化的實(shí)踐摆霉,支持暗色主題Material設(shè)計(jì)系統(tǒng)等
主題系統(tǒng)為什么容易被誤用
主題和樣式都是使用<style></style>標(biāo)簽。
主題和樣式都是以key-value的形式進(jìn)行配置晃择。
主題和樣式的區(qū)別
- 樣式設(shè)置數(shù)據(jù)和視圖相對(duì)應(yīng)磨确,可以將其理解為是一個(gè)map酿愧,使用的時(shí)候需要設(shè)置在某個(gè)具體的視圖上挺狰;主題則是設(shè)置數(shù)據(jù)和主題相對(duì)應(yīng)身隐,可以看做是一個(gè)配置存儲(chǔ)廷区,是針對(duì)全局的,而不是針對(duì)單獨(dú)的視圖贾铝。
<!--style -->
<style name="Widget.Owl.SeekBar" parent="@style/Widget.AppCompat.SeekBar">
<!--處在key位置的都是一些視圖屬性隙轻,value上的值就是可以應(yīng)用在對(duì)應(yīng)屬性上的資源。使用的時(shí)候把他們?cè)O(shè)置在某個(gè)具體的視圖上 -->
<item name="android:progressTint">@color/owl_yellow_500</item>
<item name="android:secondaryProgressTint">#99ffffff</item>
<!--?表示為按照語(yǔ)義命名的東西尋找當(dāng)前數(shù)值垢揩,個(gè)人理解也就是不同主題對(duì)應(yīng)的值-->
<item name="android:titleTextColor">?attr/colorAccent</item>
value可用的資源類型有Attribute玖绿、Boolean、Color叁巨、Dimension斑匪、Drawable、Float俘种、Font、String绝淡、Fraction宙刘。
<!--theme -->
<style name="Owl.Yellow">
<!--處在key位置是主題屬性,value上的值就是可以應(yīng)用在對(duì)應(yīng)屬性上的資源牢酵。不需要把他們?cè)O(shè)置在單獨(dú)的視圖中 -->
<item name="colorPrimary">@color/owl_yellow_500</item>
<item name="colorPrimaryVariant">@color/owl_yellow_400</item>
<item name="colorSecondary">@color/owl_blue_700</item>
<item name="colorSecondaryVariant">@color/owl_blue_800</item>
</style>
- 應(yīng)用方式不同悬包。正如上面所提到的,樣式是限定于某一個(gè)特定視圖或者視圖類型的馍乙;主題則是與上下文相關(guān)布近,并會(huì)被應(yīng)用在控件層級(jí)中垫释。
主題是可以嵌套的,Application撑瞧、Activity以及控件層級(jí)都可以指定主題棵譬。子項(xiàng)的主題會(huì)覆蓋父項(xiàng)的主題,如果只希望修改某幾個(gè)主題屬性预伺,而不希望對(duì)父項(xiàng)的其他屬性進(jìn)行修改的話订咸,可以使用ThemeOverlay:
<style name="ThemeOverlay.myTheme" parent="">
<item name="android:windowBackground">@android:color/transparent</item>
</style>
既然提到主題是與上下文相關(guān),并且是可以嵌套的酬诀,那么注意一定要使用最近的上下文脏嚷,這樣一來你堆疊在上面的主題才會(huì)被用到。建議:盡量的使用主題屬性瞒御,而不是去命名顏色父叙。
如果需要在代碼中,完成主題的疊加肴裙,可以使用ContextThemeWraper趾唱,封裝上下文,應(yīng)用另外一種主題践宴。
主題和樣式是可以相互引用的鲸匿,可以創(chuàng)建一些引用主題的樣式(比如上面提到的?attr/colorAccent),并使用可以設(shè)置樣式的主題阻肩。
應(yīng)用
- 關(guān)于顏色
ColorStateList(對(duì)應(yīng)于使用<selector></selector>標(biāo)簽定義的一系列不同狀態(tài)的color)在android L中添加了android:alpha標(biāo)簽带欢,在API23,可以引用主題屬性烤惊,在API29添加了ColorStateListDrawable乔煞。
如果要為同一種顏色設(shè)置不同的alpha值,可以定義不同的ColorStateList:
<!--first_color -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.2" android:color="?attr/colorAccent" />
</selector>
但是柒室,這樣定義的顏色不能直接作為background去設(shè)置渡贾,因?yàn)锳PI28以下是不支持的,要想在所有API等級(jí)獲的同樣的效果雄右,可以使用背景著色(app:backgroundTint)
<Button
android:id="@+id/action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:layout_centerHorizontal="true"
android:text="click me"
android:background="#000000"
app:backgroundTint="@color/first_color"/>
三個(gè)技巧
- 按照字面含義去為資源命名
不要按照語(yǔ)義命名空骚,最好按照資源命名,比如顏色就按照顏色值命名擂仍。 - 使用一致的樣式名稱
<!--Widget.app名稱/模塊名稱.視圖類名稱.變量名稱(可選囤屹,比如blue) -->
<style name="Widget.Owl.SeekBar" parent="...">
<!--Theme.app名稱/模塊名稱.變量名稱(可選) -->
<style name="Theme.Reply" parent="...">
- 分割文件
將不同的資源按照功能分割,不用都寫在一個(gè)文件里逢渔。