以往在使用ProgressBar的時候幻捏,大多數(shù)都是下面兩種情況
數(shù)據(jù)加載或者其他耗時操作的時候囤攀,使用ProgressBar給出一個正在加載的提示框
或者下載的時候贴谎,顯示一下當(dāng)前正在下載的進(jìn)度情況斤富。
最近在項目需求中,產(chǎn)品提了一個新的需求裸弦,如下
很簡單的一個頁面,只是驯击,“空吸剩余”這一項有點(diǎn)不一樣烁兰。首先想到的就是ProgressBar的進(jìn)度條樣式
趕緊xml文件里放上一個看看
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="50"/>
樣子看起來很接近需求的樣式,只是有3個地方需要修改徊都,
<1>.進(jìn)度條中間需要加上一個當(dāng)前進(jìn)度的文字描述
<2>.進(jìn)度條的當(dāng)前進(jìn)度顏色和背景色
<3>.左右兩端的圓角弧度沪斟;
明白了需求后,接下來就是動手在原有ProgressBar基礎(chǔ)上進(jìn)行修改暇矫。在平時ProgressBar的使用中主之,圖1和圖2樣式上的差距,是因為設(shè)置的這一句代碼
style="@android:style/Widget.ProgressBar.Horizontal"
直接點(diǎn)進(jìn)去可以看到系統(tǒng)已經(jīng)為我們設(shè)置好的一段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>
這里不對ProgressBar的基本屬性進(jìn)行解釋了李根,如果有不太了解的槽奕,可以查看官方文檔或者百度
根據(jù)圖3需求的樣式,需要重點(diǎn)關(guān)注的是Style里的
<item name="progressDrawable">@drawable/progress_horizontal</item>
的這一句代碼房轿,再次點(diǎn)進(jìn)去查看它的詳細(xì)代碼
<?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="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>
系統(tǒng)是通過圖層的方式粤攒,在每個 <Item /> 中從上倒下依次對應(yīng)ProgressBar的
android:background
android:secondaryProgress
android:progress
三個屬性進(jìn)行的設(shè)置。
根據(jù)需求的樣式囱持,我們要對ProgressBar做出修改夯接,也可以參照這段代碼進(jìn)行修改,從需求圖中可以看出纷妆,并不需要android:secondaryProgress 屬性的樣式盔几,所以,只修改android:background和android:progress兩個屬性就夠用了掩幢。需求中的進(jìn)度條底色是純色逊拍,上面的藍(lán)色進(jìn)度是一個由底部到頂部的藍(lán)色漸變,所以际邻,仿照系統(tǒng)的樣式芯丧,在結(jié)合需求,在drawable下自定義一個圖層樣式文件shape_inner_progressbar.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="8dip"/>
<solid android:color="#4E4562"/>
</shape>
</item>
<item
android:id="@android:id/progress"
android:bottom=".5dp"
android:left=".5dp"
android:right=".5dp"
android:top=".5dp">
<clip>
<shape>
<corners android:radius="8dip"/>
<gradient
android:angle="90"
android:endColor="#b2d8ff"
android:startColor="#1a85f2"/>
</shape>
</clip>
</item>
</layer-list>
然后在 values/styles.xml 下定義一個Style
<style name="InnerProgress" parent="android:Widget.ProgressBar.Horizontal">
<item name="android:progressDrawable">@drawable/shape_inner_progressbar</item>
</style>
在activity的xml中使用
<ProgressBar
android:layout_width="match_parent"
style="@style/InnerProgress"
android:progress="60"
android:layout_centerInParent="true"
android:layout_height="wrap_content"/>
運(yùn)行起來看一下效果世曾,自我感覺很是良好注整。
現(xiàn)在就差最后一步,在進(jìn)度條中間設(shè)置當(dāng)前進(jìn)度的百分比數(shù)值。這里就不能直接通過屬性值設(shè)置了肿轨,需要繼承ProgressBar并且重寫它的onDraw方法寿冕,然后通過getProgress()方法拿到它當(dāng)前進(jìn)度并且繪制在進(jìn)度條中間位置,也很簡單椒袍,代碼如下
public class InnerProgressBar extends ProgressBar {
private Paint mPaint;
private Rect mRect;
public InnerProgressBar (Context context) {
super (context);
init ();
}
public InnerProgressBar (Context context, AttributeSet attrs) {
super (context, attrs);
init ();
}
private void init () {
mPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
mPaint.setColor (Color.WHITE);
mPaint.setTextAlign (Paint.Align.CENTER);
mPaint.setTextSize (35);
mRect = new Rect ();
}
@Override
protected synchronized void onDraw (Canvas canvas) {
super.onDraw (canvas);
String text = String.valueOf (getProgress ()) + "%";
mPaint.getTextBounds (text, 0, text.length (), mRect);
canvas.drawText (text, getWidth () / 2, getHeight () / 2 + mRect.height () / 2, mPaint);
}
}
這里需要注意一點(diǎn)的是驼唱,為了在Y軸方向上也保持文字居中,需要拿到文字高度的一半驹暑,通過和getHeight () / 2一起的和作為繪制文字的Y坐標(biāo)玫恳,至此,整個效果就出來了优俘,上圖:
整體代碼看起來很簡單京办,只是以前從沒深入的去了解過ProgressBar,都是直接使用它的原生效果帆焕,導(dǎo)致一直覺得這是一個使用方式很單一的控件