系統(tǒng)主題樣式-以ProgressBar為例

這篇文章將分析系統(tǒng)ProgressBar的主題及樣式

當前應用環(huán)境:

compileSdkVersion 24
targetSdkVersion 24
Theme.AppCompat.Light
appcompat-v7:25.3.1

先來看看系統(tǒng)ProgressBar的繼承結構
ProgressBar繼承自View,常見的子類包括SeekBar及RatingBar

By default, the progress bar is a spinning wheel (an indeterminate indicator).
進度條默認情況下為無進度圓形樣式
如果改成條形XML中使用style="@android:style/Widget.ProgressBar.Horizontal"

我們來驗證一下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ProgressBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

android24模擬器顯示效果:


1.gif

但是在android19模擬器上的效果為:


2.gif

更神奇的是android19模擬器上改變一下背景顏色:


3.gif

雖然默認都是無進度的圓形,但是效果為什么不一樣?

主題樣式原碼分析

關于Activity是如何加載對應的主題,請參考:https://www.cnblogs.com/chenxibobo/p/6136681.html
總之最后調用Resources中的selectSystemTheme函數。

    Resources.java
    public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
        return selectSystemTheme(curTheme, targetSdkVersion,
                com.android.internal.R.style.Theme,
                com.android.internal.R.style.Theme_Holo,
                com.android.internal.R.style.Theme_DeviceDefault,
                com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
    }

    public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
            int dark, int deviceDefault) {
        if (curTheme != 0) {//如果設置了主題灌闺,直接返回
            return curTheme;
        }
        //沒有設置的情況下栅组,如果targetSdkVersion 小于11則返回R.style.Theme
        if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
            return orig;
        }
        //targetSdkVersion 如果小于14則返回R.style.Theme_Holo
        if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return holo;
        }
        //targetSdkVersion 如果小于24則返回R.style.Theme_DeviceDefault
        if (targetSdkVersion < Build.VERSION_CODES.N) {
            return dark;
        }
        return deviceDefault;//返回R.style.Theme_DeviceDefault_Light_DarkActionBar
    }

我們當前設置了主題墓猎,并且主題為Theme.AppCompat.Light夯膀。

appcompat-v7包 values.xml

    //對于父類主題陨囊,不同Android版本對應不同版本的values.xml,查看下圖
    <style name="Theme.AppCompat.Light" parent="Base.Theme.AppCompat.Light"/>
    <style name="Base.Theme.AppCompat.Light" parent="Base.V7.Theme.AppCompat.Light">
    //Theme.AppCompat.Light主題阻肩,最終都會采用該主題,下面會具體分析
    <style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
    </style>

查看Base.Theme.AppCompat.Light运授,不同Android版本對應相應的values.xml


image.png

appcompat-v7包 values-v23.xml

    <style name="Base.Theme.AppCompat.Light" parent="Base.V23.Theme.AppCompat.Light"/>
    <style name="Base.V23.Theme.AppCompat.Light" parent="Base.V22.Theme.AppCompat.Light">
      ...
    </style>

appcompat-v7包 values-v22.xml

    <style name="Base.Theme.AppCompat.Light" parent="Base.V22.Theme.AppCompat.Light"/>
    <style name="Base.V22.Theme.AppCompat.Light" parent="Base.V21.Theme.AppCompat.Light">
       ...
    </style>

appcompat-v7包 values-v21.xml

    <style name="Base.Theme.AppCompat.Light" parent="Base.V21.Theme.AppCompat.Light"/>
    <style name="Base.V21.Theme.AppCompat.Light" parent="Base.V7.Theme.AppCompat.Light">
       ...
    </style>

最終到達之前提到的 appcompat-v7包 values.xml

    //Theme.AppCompat.Light主題烤惊,最終都會采用該主題
    <style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
    </style>

查看Platform.AppCompat.Light


11.png
注意乔煞,這里就是為什么不同android 版本顯示的效果不同的原因。

appcompat-v7包 values-v25.xml

    <style name="Platform.AppCompat.Light" parent="Platform.V25.AppCompat.Light"/>
    <style name="Platform.V25.AppCompat.Light" parent="android:Theme.Material.Light.NoActionBar">
    </style>

appcompat-v7包 values-v21.xml

    <style name="Platform.AppCompat.Light" parent="Platform.V21.AppCompat.Light"/>
    <style name="Platform.V21.AppCompat.Light" parent="android:Theme.Material.Light.NoActionBar">
       ...
    </style>
5.0及以上主題為android:Theme.Material

appcompat-v7包 values-v14.xml

    <style name="Platform.AppCompat.Light" parent="Platform.V14.AppCompat.Light"/>
    <style name="Platform.V14.AppCompat.Light" parent="Platform.V11.AppCompat.Light">
      ...
    </style>

appcompat-v7包 values-v11.xml

    <style name="Platform.AppCompat.Light" parent="Platform.V11.AppCompat.Light"/>
    <style name="Platform.V11.AppCompat.Light" parent="android:Theme.Holo.Light">
      ...
    </style>

3.0及以上主題為android:Theme.Holo

appcompat-v7包 values.xml

    <style name="Platform.AppCompat.Light" parent="android:Theme.Light">
      ...
    </style>

3.0以下主題為android:Theme

到此與Resources類中的selectSystemTheme()方法便能對應上了柒室。

我們來分析1.gif(Android 24):

系統(tǒng)根據Android版本渡贾,這里會選擇android:Theme.Material.Light.NoActionBar主題,繼承自android:Theme.Material.Light雄右。

themes_material.xml

    <style name="Theme.Material.Light" parent="Theme.Light">
        <!-- Widget styles -->
        <item name="progressBarStyle">@style/Widget.Material.Light.ProgressBar</item>
    </style>
    <style name="Widget.Material.Light.ProgressBar" parent="Widget.Material.ProgressBar"/>

styles_material.xml

    <style name="Widget.Material.ProgressBar" parent="Widget.ProgressBar">
        <item name="indeterminateDrawable">@drawable/progress_medium_material</item>
    </style>

progress_medium_material.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector_drawable_progress_bar_medium" >

    <target
        android:name="progressBar"
        android:animation="@anim/progress_indeterminate_material" />

    <target
        android:name="root"
        android:animation="@anim/progress_indeterminate_rotation_material" />
</animated-vector>

這里不再詳細分析此Drawable空骚,這里涉及到AnimatedVectorDrawable, SVG等相關內容
可以參考我的另一篇文章Android SVG
至此,1.gif的效果便分析完成了不脯。

我們再來分析2.gif 及3.gif

其實這兩張圖片是完全一模一樣的府怯,只不過圖2因為背景與控件Drawable中的部分內容顏色相同,沒有顯示出來而已防楷。
這兩張圖相對應的android版本為19,主題為android:Theme.Holo.Light

themes_holo.xml

    <style name="Theme.Holo.Light" parent="Theme.Light">
        <!-- Widget styles -->
        <item name="progressBarStyle">@style/Widget.Holo.Light.ProgressBar</item>

    </style>

styles_holo.xml

    <style name="Widget.Holo.Light.ProgressBar" parent="Widget.Holo.ProgressBar" />
    <style name="Widget.Holo.ProgressBar" parent="Widget.ProgressBar">
        <item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
    </style>

progress_medium_holo.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    //兩張圖片同時相反方向旋轉牺丙,同一時間旋轉的角度不同,造成自轉的效果复局。
    <item>
        <rotate
             android:drawable="@drawable/spinner_48_outer_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="0"
             android:toDegrees="1080" />
    </item>
    <item>
        <rotate
             android:drawable="@drawable/spinner_48_inner_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="720"
             android:toDegrees="0" />
    </item>
</layer-list>

@drawable/spinner_48_outer_holo


image.png

@drawable/spinner_48_inner_holo


image.png

至此冲簿,2.gif 3.gif的效果便分析完了。

接下來我們去掉Application主題亿昏,看一下效果:
progress.gif

因為當前的的targetSdkVersion 是24峦剔,所以Resources.selectSystemTheme()返回的主題是R.style.Theme_DeviceDefault_Light_DarkActionBar。

我們分析下原碼:

themes_device_defaults.xml

    <style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Material.Light.DarkActionBar" />

themes_material.xml 貌似沒有看到相關的屬性

    <style name="Theme.Material.Light.DarkActionBar">
        <item name="actionBarWidgetTheme">@null</item>
        <item name="actionBarTheme">@style/ThemeOverlay.Material.Dark.ActionBar</item>
        <item name="popupTheme">@style/ThemeOverlay.Material.Light</item>       
        <item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
        <item name="colorPrimary">@color/primary_material_dark</item>
    </style>

themes_material.xml 父類主題

    <!-- Material theme (light version). -->
    <style name="Theme.Material.Light" parent="Theme.Light">
        <!-- Widget styles -->
        <item name="progressBarStyle">@style/Widget.Material.Light.ProgressBar</item>
        <!-- Color palette -->
        //progressbar的indeterminateDrawable中控件的顏色設置為android:tint="?attr/colorControlActivated"
        <item name="colorControlActivated">?attr/colorAccent</item>
        //最終指向colorAccent的顏色
        <item name="colorAccent">@color/accent_material_light</item>
    </style>

styles_material.xml

<style name="Widget.Material.Light.ProgressBar" parent="Widget.Material.ProgressBar"/>

再一次看到Widget.Material.ProgressBar角钩。

colors_material.xml

    <color name="accent_material_light">@color/material_deep_teal_500</color>
    <color name="material_deep_teal_500">#ff009688</color>//正是我們控件的顏色吝沫。

所以progressbar的indeterminateDrawable沒有改變,只是顏色改變了递礼。

參考:

https://www.cnblogs.com/chenxibobo/p/6136681.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末惨险,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子脊髓,更是在濱河造成了極大的恐慌辫愉,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件将硝,死亡現場離奇詭異恭朗,居然都是意外死亡,警方通過查閱死者的電腦和手機依疼,發(fā)現死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門痰腮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人律罢,你說我怎么就攤上這事诽嘉。” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵虫腋,是天一觀的道長。 經常有香客問我稀余,道長悦冀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任睛琳,我火速辦了婚禮盒蟆,結果婚禮上,老公的妹妹穿的比我還像新娘师骗。我一直安慰自己历等,他們只是感情好,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布辟癌。 她就那樣靜靜地躺著寒屯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黍少。 梳的紋絲不亂的頭發(fā)上寡夹,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音厂置,去河邊找鬼菩掏。 笑死,一個胖子當著我的面吹牛昵济,可吹牛的內容都是我干的智绸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼访忿,長吁一口氣:“原來是場噩夢啊……” “哼瞧栗!你這毒婦竟也來了?” 一聲冷哼從身側響起醉顽,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤沼溜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后游添,有當地人在樹林里發(fā)現了一具尸體系草,經...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年唆涝,在試婚紗的時候發(fā)現自己被綠了找都。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡廊酣,死狀恐怖能耻,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤晓猛,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布饿幅,位于F島的核電站,受9級特大地震影響戒职,放射性物質發(fā)生泄漏栗恩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一洪燥、第九天 我趴在偏房一處隱蔽的房頂上張望磕秤。 院中可真熱鬧,春花似錦捧韵、人聲如沸市咆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒙兰。三九已至,卻和暖如春其弊,著一層夾襖步出監(jiān)牢的瞬間癞己,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工梭伐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留痹雅,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓糊识,卻偏偏與公主長得像绩社,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赂苗,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348