自定義ProgressBar(一)

ProgressBar是一個非常重要組件棺榔。通常用于向用戶顯示耗時操作完成的百分比快鱼。主要包括水平和圓形兩種類型雕薪。講解之前首先來講一下樣式屬性設(shè)置胶哲,這個在自定義里面是核心部分憎蛤。
  本文主要介紹ProgressBar的屬性里面的 progressDrawable 和 indeterminateDrawable

一、常用屬性

(一)關(guān)于style屬性設(shè)置:安卓支持幾種風(fēng)格的進度條纪吮,通過style屬性可以為ProgressBar設(shè)置指定風(fēng)格俩檬,該屬性可支持如下幾個屬性值:
  1. 安卓styles.xml里面的 8個,這8個兼容不同系統(tǒng)版本碾盟,一般都用這些style樣式用的多
屬性值 屬性的含義
style="@android:style/Widget.ProgressBar"
style="@android:style/Widget.ProgressBar.Large" 大環(huán)形進度條
style="@android:style/Widget.ProgressBar.Small" 小環(huán)形進度條
style="@android:style/Widget.ProgressBar.Inverse" 普通大小的環(huán)形進度條
style="@android:style/Widget.ProgressBar.Large.Inverse" 大環(huán)形進度條
style="@android:style/Widget.ProgressBar.Small.Inverse" 小環(huán)形進度條
style="@android:style/Widget.ProgressBar.Small.Title" 標題欄環(huán)形進度條
style="@android:style/Widget.ProgressBar.Horizontal" 水平進度條
<style name="Widget.ProgressBar">
    <item name="indeterminateOnly">true</item>
    <item name="indeterminateDrawable">@drawable/progress_medium_white</item>
    <item name="indeterminateBehavior">repeat</item>
    <item name="indeterminateDuration">3500</item>
    <item name="minWidth">48dip</item>
    <item name="maxWidth">48dip</item>
    <item name="minHeight">48dip</item>
    <item name="maxHeight">48dip</item>
    <item name="mirrorForRtl">false</item>
</style>

<style name="Widget.ProgressBar.Large">
    <item name="indeterminateDrawable">@drawable/progress_large_white</item>
    <item name="minWidth">76dip</item>
    <item name="maxWidth">76dip</item>
    <item name="minHeight">76dip</item>
    <item name="maxHeight">76dip</item>
</style>

<style name="Widget.ProgressBar.Small">
    <item name="indeterminateDrawable">@drawable/progress_small_white</item>
    <item name="minWidth">16dip</item>
    <item name="maxWidth">16dip</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

<style name="Widget.ProgressBar.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_medium</item>
</style>

<style name="Widget.ProgressBar.Large.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_large</item>
</style>

<style name="Widget.ProgressBar.Small.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_small</item>
</style>

<style name="Widget.ProgressBar.Small.Title">
    <item name="indeterminateDrawable">@drawable/progress_small_titlebar</item>
</style>

<style name="Widget.ProgressBar.Horizontal">
    <item name="indeterminateOnly">false</item>
    <item name="progressDrawable">@drawable/progress_horizontal</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal</item>
    <item name="minHeight">20dip</item>
    <item name="maxHeight">20dip</item>
    <item name="mirrorForRtl">true</item>
</style>

2.styles_holo.xml里面的 16個棚辽,其中Widget.Holo.開頭的有8個,Widget.Holo.Light.開頭的有8個

----------------------------------------------- Widget.Holo.開頭的 ------------------------------------------------------

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

<style name="Widget.Holo.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_holo_dark</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

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

<style name="Widget.Holo.ProgressBar.Small.Title" />

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

<style name="Widget.Holo.ProgressBar.Inverse" />

<style name="Widget.Holo.ProgressBar.Small.Inverse" />

<style name="Widget.Holo.ProgressBar.Large.Inverse" />

--------------------------------------------- Widget.Holo.Light.開頭的 ----------------------------------------------------

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

<style name="Widget.Holo.Light.ProgressBar.Horizontal" parent="Widget.Holo.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_holo_light</item>
</style>

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

<style name="Widget.Holo.Light.ProgressBar.Small.Title" parent="Widget.Holo.ProgressBar.Small.Title" />

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

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

<style name="Widget.Holo.Light.ProgressBar.Small.Inverse" parent="Widget.Holo.ProgressBar.Small.Inverse" />

<style name="Widget.Holo.Light.ProgressBar.Large.Inverse" parent="Widget.Holo.ProgressBar.Large.Inverse" />

3.styles_material.xml里面的 16個冰肴,其中Widget.Material.開頭的有8個屈藐,Widget.Material.Light.開頭的有8個

----------------------------------------------- Widget.Material.開頭的 ------------------------------------------------------

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

<style name="Widget.Material.ProgressBar.Inverse"/>

<style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_material</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

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

<style name="Widget.Material.ProgressBar.Small.Inverse"/>
<style name="Widget.Material.ProgressBar.Small.Title"/>

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

<style name="Widget.Material.ProgressBar.Large.Inverse"/>

-------------------------------------------- Widget.Material.Light.開頭的 ---------------------------------------------------

<style name="Widget.Material.Light.ProgressBar" parent="Widget.Material.ProgressBar"/>
<style name="Widget.Material.Light.ProgressBar.Horizontal" parent="Widget.Material.ProgressBar.Horizontal"/>
<style name="Widget.Material.Light.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>
<style name="Widget.Material.Light.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>
<style name="Widget.Material.Light.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>
<style name="Widget.Material.Light.ProgressBar.Inverse" parent="Widget.Material.ProgressBar.Inverse"/>
<style name="Widget.Material.Light.ProgressBar.Small.Inverse" parent="Widget.Material.ProgressBar.Small.Inverse"/>
<style name="Widget.Material.Light.ProgressBar.Large.Inverse" parent="Widget.Material.ProgressBar.Large.Inverse"/>

4.styles_device_default.xml里面的13個,其中Widget.DeviceDefault.開頭的有5個熙尉,
Widget.DeviceDefault.Light.開頭的有8個联逻。

------------------------------------------- Widget.DeviceDefault..開頭的 --------------------------------------------------

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

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

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

<style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>

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

---------------------------------------- Widget.DeviceDefault.Light.開頭的 -----------------------------------------------

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

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

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

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

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

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

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

<style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" 
    parent="Widget.Material.Light.ProgressBar.Large.Inverse"/>
(二)其他屬性
屬性值 描述
android:max="" 進度條最大值
android:progress="" 進度條已完成值
android:secondaryProgress="" 二級進度值,值介于0到max检痰。該進度在主進度和背景之間包归。比如用于網(wǎng)絡(luò)播放視頻時,二級進度用于表示緩沖進度铅歼,主進度用于表示播放進度公壤。
android:animationResolution 超時的動畫幀之間的毫秒 ;必須是一個整數(shù)值,如“100”椎椰。(已經(jīng)被舍棄了厦幅,現(xiàn)在都不用了。)
android:progressDrawable="" 設(shè)置進度條軌道對應(yīng)的drawable對象
android:indeterminate="" 是否允許使用不確定模式慨飘,該屬性設(shè)置為true确憨,表示設(shè)置進度條不精確顯示進度,在不確定模式下瓤的,進度條動畫無限循環(huán)
android:indeterminateDrawable="" 定義不確定模式是否可拉
android:indeterminateDuration="" 時間不定的動畫
android:indeterminateBehavior="" 定義當(dāng)進度達到最大時休弃,不確定模式的表現(xiàn);該值必須為repeat或者cycle堤瘤,repeat表示進度從0重新開始玫芦;cycle表示進度保持當(dāng)前值,并且回到0
android:indeterminateOnly="" 限制為不定模式
android:indeterminateTint=""
android:indeterminateTintMode=""

二本辐、水平的ProgressBar

1.首先是布局代碼:

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#3C7793"
    android:orientation="vertical">

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="0"
        android:secondaryProgress="100"
        android:progressDrawable="@drawable/progressbar_line" />
</LinearLayout>

2.再看drawable目錄下的progressbar_line.xml是怎么定義的:(第一個item是背景桥帆,第二個item是二級進度值,一般用于視頻的緩沖,最后一個是顯示的進度)

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#ff9d9e9d"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:angle="0"
                />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                    android:startColor="#80ffd300"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:angle="0"
                    />
            </shape>
        </clip>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners
                    android:radius="5dip" />
                <gradient
                    android:startColor="#80ff0000"
                    android:endColor="#8000ff00"
                    android:angle="0" />
            </shape>
        </clip>
    </item>
  </layer-list>

3.代碼里面控制進度的顯示慎皱,新建一個線程,重寫runnable老虫,在run方法里面去模擬執(zhí)行耗時操作,通過handler發(fā)消息給主線程茫多,主線程拿到消息之后更新UI.

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ProgressBar;

public class MainActivity extends AppCompatActivity {
   
    private ProgressBar progressBar1;

    //在這里處理更新進度條
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0x0001:
                    progressBar1.setProgress(msg.arg1);
                    //如果進度小于100,則延遲100毫秒之后重復(fù)執(zhí)行runnable
                    if(msg.arg1<100){
                        mHandler.postDelayed(r, 100);
                    }else{
                        //否則祈匙,都置零,線程重新執(zhí)行
                        progressBar1.setProgress(0);
                        mHandler.post(r);
                    }
                    break;
            }
        }
    };

    Runnable r = new Runnable() {
        int currentProgress = 0;
        @Override
        public void run() {
            Message msg = new Message();
            msg.what = 0x0001;
            currentProgress = progressBar1.getProgress()+1;
            progressBar1.setProgress(currentProgress);
            msg.arg1 = currentProgress;
            mHandler.sendMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
        progressBar1.setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_line));

        if(progressBar1.getProgress() < progressBar1.getMax()){
            // 把r加入到線程隊列,然后線程隊列里就開始執(zhí)行runnable對象中的run()
            mHandler.post(r);
        }else{//不用的時候夺欲,就把r從線程隊列移除跪帝,這是一個小的性能優(yōu)化
            mHandler.removeCallbacks(r);
        }
    }
}

三、圓形的ProgressBar

1.先來看看布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#3C7793"
android:orientation="vertical">

    <ProgressBar
        android:id="@+id/loadProgressBar"
        style="@android:style/Widget.ProgressBar"
        android:layout_margin="10dp"
        android:indeterminateDrawable="@drawable/progressbar_round"
        android:layout_width="100dp"
        android:layout_height="100dp" />
</LinearLayout>

2.再看看drawable目錄下的progressbar_round.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">

    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="10"
        android:useLevel="false">

        <gradient
            android:centerColor="#FFFFFF"
            android:centerY="0.50"
            android:endColor="#FFFF00"
            android:startColor="#00FFFF"
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</rotate>

效果圖如下:

ProgressBar演示.gif

下一篇我們重點講解如何寫一個View繼承ProgressBar些阅,實現(xiàn)各種吊炸天的效果伞剑。


相關(guān)文章閱讀:

全面總結(jié)側(cè)滑菜單的4種實現(xiàn)方式

萬能的dialog庫(包括類似popwindow效果) 
 
  自定義ViewPager實現(xiàn)3D畫廊效果

簡單幾行代碼讓ViewPager實現(xiàn)垂直滑動效果

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市市埋,隨后出現(xiàn)的幾起案子黎泣,更是在濱河造成了極大的恐慌,老刑警劉巖缤谎,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抒倚,死亡現(xiàn)場離奇詭異,居然都是意外死亡坷澡,警方通過查閱死者的電腦和手機托呕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洋访,“玉大人镣陕,你說我怎么就攤上這事∫稣” “怎么了呆抑?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長汁展。 經(jīng)常有香客問我鹊碍,道長,這世上最難降的妖魔是什么食绿? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任侈咕,我火速辦了婚禮,結(jié)果婚禮上器紧,老公的妹妹穿的比我還像新娘耀销。我一直安慰自己,他們只是感情好铲汪,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布熊尉。 她就那樣靜靜地躺著,像睡著了一般掌腰。 火紅的嫁衣襯著肌膚如雪狰住。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天齿梁,我揣著相機與錄音催植,去河邊找鬼肮蛹。 笑死,一個胖子當(dāng)著我的面吹牛创南,可吹牛的內(nèi)容都是我干的伦忠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扰藕,長吁一口氣:“原來是場噩夢啊……” “哼缓苛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邓深,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笔刹,沒想到半個月后芥备,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡舌菜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年萌壳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片日月。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡袱瓮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出爱咬,到底是詐尸還是另有隱情尺借,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布精拟,位于F島的核電站燎斩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蜂绎。R本人自食惡果不足惜栅表,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望师枣。 院中可真熱鬧怪瓶,春花似錦、人聲如沸践美。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拨脉。三九已至哆姻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玫膀,已是汗流浹背矛缨。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箕昭。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓灵妨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親落竹。 傳聞我的和親對象是個殘疾皇子泌霍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容