五分了解Android?Progress?Bar進(jìn)度條加載
1、前言
最近在開發(fā)中,同事對(duì)于android.widget下的控件一知半解,又恰好那天用到了Seekbar,想了想,那就從Seekbar's father ProgressBar 來說說android.widget下的常用控件和常用用法吧。后面也會(huì)根據(jù)這些控件來進(jìn)行仿寫、擴(kuò)展,做一些高度自定義的View啦。如果寫的不好,或者有錯(cuò)誤之處,懇請(qǐng)?jiān)谠u(píng)論、私信、郵箱指出,萬分感謝??
2、ProgressBar
A user interface element that indicates the progress of an operation.
使用很簡(jiǎn)單,看看一些基本的屬性
android:max:進(jìn)度條的最大值
android:progress:進(jìn)度條已完成進(jìn)度值
android:progressDrawable:設(shè)置軌道對(duì)應(yīng)的Drawable對(duì)象
android:indeterminate:如果設(shè)置成true,則進(jìn)度條不精確顯示進(jìn)度(會(huì)一直進(jìn)行動(dòng)畫)
android:indeterminateDrawable:設(shè)置不顯示進(jìn)度的進(jìn)度條的Drawable對(duì)象
android:indeterminateDuration:設(shè)置不精確顯示進(jìn)度的持續(xù)時(shí)間
android:secondaryProgress:二級(jí)進(jìn)度條(使用場(chǎng)景不多)
直接在布局中使用即可
<ProgressBar
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<ProgressBar
style="@android:style/Widget.ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<ProgressBar
android:id="@+id/sb_no_beautiful"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:max="100"
android:progress="50"
android:secondaryProgress="70" />
<ProgressBar
android:id="@+id/sb_no_beautiful2"
style="@android:style/Widget.Holo.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:indeterminate="true"
android:max="100"
android:progress="50"
android:secondaryProgress="70" />
分別就對(duì)應(yīng)以下圖片咯

但是這種樣式,不得不懷疑Google之前的審美,肯定是不滿意的,怎么換樣式呢。
看看XML文件,很容易發(fā)現(xiàn),這幾個(gè)ProgressBar的差異是因?yàn)閟tyle引起的,隨手點(diǎn)開一個(gè)@android:style/Widget.ProgressBar.Horizontal 看看。
<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>
很好,估摸著樣式就出在progressDrawable/indeterminateDrawable上面,看看 @drawable/progress_horizontal 里面
<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="270"/>
</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="270"/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"/>
</shape>
</clip>
</item>
</layer-list>
一個(gè)樣式文件,分別操控了background/secondaryProgress/progress,這樣我們很容易推測(cè)出

再看看 @drawable/progress_indeterminate_horizontal
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />
<item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />
<item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />
</animation-list>
顯而易見,這是indeterminate模式下的樣式啊,那我們仿寫一個(gè)不同樣式,就很簡(jiǎn)單了,動(dòng)手。
styles.xml
<style name="ProgressBar_Beautiful" >
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/progress_horizontal_1</item>
<item name="android:indeterminateDrawable">@drawable/progress_indeterminate_beautiful</item>
<item name="android:mirrorForRtl">true</item>
</style>
progress_horizontal_1.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="25dp" />
<solid android:color="#FFF0F0F0"/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="25dp" />
<solid android:color="#FFC0EC87"/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="25dp" />
<solid android:color="#FFA5E05B"/>
</shape>
</clip>
</item>
</layer-list>
progress_indeterminate_beautiful.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/bg_progress_001" android:duration="200" />
<item android:drawable="@drawable/bg_progress_002" android:duration="200" />
<item android:drawable="@drawable/bg_progress_003" android:duration="200" />
<item android:drawable="@drawable/bg_progress_004" android:duration="200" />
</animation-list>
吭呲吭呲就寫出來了,看看效果

換了個(gè)顏色,加了個(gè)圓角/ 換了個(gè)圖片,還行。
我沒有去再寫環(huán)形的ProgressBar了,因?yàn)樗褪莻€(gè)一個(gè)圖,瘋狂的在旋轉(zhuǎn)。
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/spinner_white_76"
android:pivotX="50%"
android:pivotY="50%"
android:framesCount="12"
android:frameDuration="100" />
還有一些屬性我就不贅述了。你可以根據(jù)官方的樣式,修一修、改一改,就可以滿足一些基本的需求了。
用起來就這么簡(jiǎn)單,就是因?yàn)樘?jiǎn)單,更復(fù)雜的功能就不是ProgressBar能直接實(shí)現(xiàn)的了。比如帶個(gè)滑塊?
3、SeekBar
好吧,ProgressBar的一個(gè)子類,也在android.widget下,因?yàn)槭侵苯永^承,而且就加了個(gè)滑塊相關(guān)的代碼,實(shí)際上它也非常簡(jiǎn)單,然我們來看看
<SeekBar
android:id="@+id/sb_01"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:thumbOffset="1dp"
android:max="100"
android:progress="50"
android:secondaryProgress="70"
android:splitTrack="false"
android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
android:id="@+id/sb_02"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:max="100"
android:progress="50"
android:secondaryProgress="70"
android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
android:id="@+id/sb_03"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:max="100"
android:progress="100"
android:secondaryProgress="70"
android:splitTrack="false"
android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
android:id="@+id/sb_04"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:thumbOffset="1dp"
android:max="100"
android:progress="100"
android:secondaryProgress="70"
android:splitTrack="false"
android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
android:id="@+id/sb_05"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:max="100"
android:paddingHorizontal="0dp"
android:progress="50"
android:secondaryProgress="70"
android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
android:id="@+id/sb_06"
style="@style/ProgressBar_Beautiful"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginVertical="10dp"
android:max="100"
android:progress="50"
android:secondaryProgress="70"
android:thumb="@null" />
樣式就在下面了

因?yàn)镾eekbar相較而言就多了個(gè)thumb(就是那個(gè)滑塊),所以就著重說一下滑塊,其他的就一筆帶過咯。
主要了解的是如何設(shè)置自己的thumb和thumb的各種問題
android:thumb="@drawable/icon_seekbar_thum"
設(shè)置就這么thumb簡(jiǎn)單,一個(gè)drawable文件解決,我這里對(duì)應(yīng)的是單一圖片,不過Google的是帶有多種狀態(tài)的thumb,我們來看看官方是如何實(shí)現(xiàn)的
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true">
<item android:state_enabled="false" android:state_pressed="true">
<bitmap android:src="@drawable/abc_scrubber_control_off_mtrl_alpha"android:gravity="center"/>
</item>
<item android:state_enabled="false">
<bitmap android:src="@drawable/abc_scrubber_control_off_mtrl_alpha"android:gravity="center"/>
</item>
<item android:state_pressed="true">
<bitmap android:src="@drawable/abc_scrubber_control_to_pressed_mtrl_005" android:gravity="center"/>
</item>
<item>
<bitmap android:src="@drawable/abc_scrubber_control_to_pressed_mtrl_000"android:gravity="center"/>
</item>
</selector>
引用一個(gè)drawable,也是一個(gè)熟知的selector組,通過對(duì)應(yīng)的item,我們就可以實(shí)現(xiàn)在不同的狀態(tài)下顯示不同的thumb了,具體的樣式我就不寫了,再說ProgressBar的樣式的時(shí)候也是有類似的操作的
不過你可能發(fā)現(xiàn)了,其實(shí)這幾個(gè)樣式看起來都差不多,是因?yàn)槎际俏沂褂肧eekbar遇到的問題以及解決方法,我們細(xì)說
(1) 自定義的thumb的背景會(huì)裁剪出一個(gè)正方形,這對(duì)于不規(guī)則圖形來講是非常難看的

很簡(jiǎn)單一行
android:splitTrack="false"
修復(fù)0。0
(2)thumb的中心點(diǎn)對(duì)齊bar的邊界,所以thumb是允許超出進(jìn)度條一點(diǎn)的。有時(shí)候我們不需要

很簡(jiǎn)單一行
android:thumbOffset="1dp"
修復(fù)0,0
(3) 你可能發(fā)現(xiàn)就算沒有寫margin和padding,seekbar也不會(huì)占滿父布局的,是因?yàn)樗詭adding,所以如果需要去掉

很簡(jiǎn)單一行
android:paddingHorizontal="0dp"
修復(fù)0>0
(4)最后一個(gè),SeekBar但是不想要滑塊!為什么不用ProgressBar呢?沒別的就是頭鐵!
很簡(jiǎn)單一行
android:thumb="@null"
修復(fù)0」0
但是要注意的是,此時(shí)Seekbar還是能點(diǎn)擊的!所以需要把點(diǎn)擊事件攔截掉
sb02.setOnTouchListener { _, _ -> true }
真的修復(fù)0[]0
好了好了,thumb的監(jiān)聽事件還沒說呢
sb01.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
//進(jìn)度發(fā)生改變時(shí)會(huì)觸發(fā)
}
override fun onStartTrackingTouch(p0: SeekBar?) {
//按住SeekBar時(shí)會(huì)觸發(fā)
}
override fun onStopTrackingTouch(p0: SeekBar?) {
//放開SeekBar時(shí)觸發(fā)
}
})
沒啦,Seekbar就這么多。
還有一個(gè),放在下次講吧
對(duì)了,如果你感覺你的ProgressBar不夠流暢,可以用以下這個(gè)
bar.setProgress(progress, true)
4、結(jié)尾
更多復(fù)雜的進(jìn)度條需求,靠widget的控件,肯定是難以實(shí)現(xiàn)的,我們接下來會(huì)講述RatingBar,以及繼承ProgressBar,做更多好看的進(jìn)度條!
以上就是五分了解Android Progress Bar進(jìn)度條加載的詳細(xì)內(nèi)容,更多關(guān)于Android Progress Bar的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android入門之彈出式對(duì)話框的實(shí)現(xiàn)
- Android入門之利用Spinner實(shí)現(xiàn)彈出選擇對(duì)話框
- Android對(duì)話框使用方法詳解
- Android自定義對(duì)話框的簡(jiǎn)單實(shí)現(xiàn)
- Android開發(fā)基礎(chǔ)使用ProgressBar加載進(jìn)度條示例
- Android自定義View實(shí)現(xiàn)進(jìn)度條動(dòng)畫
- Android實(shí)現(xiàn)簡(jiǎn)單實(shí)用的垂直進(jìn)度條
- android實(shí)現(xiàn)簡(jiǎn)單進(jìn)度條ProgressBar效果
- Jetpack Compose實(shí)現(xiàn)對(duì)話框和進(jìn)度條實(shí)例解析
相關(guān)文章
Android RecyclerView緩存復(fù)用原理解析
RecyclerView是Android一個(gè)更強(qiáng)大的控件,其不僅可以實(shí)現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實(shí)現(xiàn)數(shù)據(jù)縱向滾動(dòng),也可以實(shí)現(xiàn)橫向滾動(dòng)(ListView做不到橫向滾動(dòng))。接下來講解RecyclerView的用法2022-11-11
Android四大組件之廣播BroadcastReceiver詳解
Android開發(fā)的四大組件分別是:活動(dòng)(activity),用于表現(xiàn)功能;服務(wù)(service),后臺(tái)運(yùn)行服務(wù),不提供界面呈現(xiàn);廣播接受者(Broadcast Receive),勇于接收廣播;內(nèi)容提供者(Content Provider),支持多個(gè)應(yīng)用中存儲(chǔ)和讀取數(shù)據(jù),相當(dāng)于數(shù)據(jù)庫(kù),本篇著重介紹廣播組件2021-11-11
Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension wit
今天小編就為大家分享一篇關(guān)于Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension with name 'android'的解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Android中Fragment多層嵌套時(shí)onActivityResult無法正確回調(diào)問題的解決方法
這篇文章主要介紹了Android中Fragment多層嵌套時(shí)onActivityResult無法正確回調(diào)問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Android 實(shí)現(xiàn)沉浸式狀態(tài)欄的方法
沉浸式狀態(tài)欄的來源就是很多手機(jī)用的是實(shí)體按鍵,沒有虛擬鍵,于是開了沉浸模式就只有狀態(tài)欄消失了。下面腳本之家小編給大家介紹Android 實(shí)現(xiàn)沉浸式狀態(tài)欄,需要的朋友可以參考下2015-09-09
Android 自定義view模板并實(shí)現(xiàn)點(diǎn)擊事件的回調(diào)
這篇文章主要介紹了Android 自定義view模板并實(shí)現(xiàn)點(diǎn)擊事件的回調(diào)的相關(guān)資料,需要的朋友可以參考下2017-01-01

