Android ProgressBar(進(jìn)度條)

2023-03-31 13:41 更新

本節(jié)引言:

本節(jié)給大家?guī)淼氖茿ndroid基本UI控件中的ProgressBar(進(jìn)度條),ProgressBar的應(yīng)用場景很多,比如 用戶登錄時,后臺在發(fā)請求,以及等待服務(wù)器返回信息,這個時候會用到進(jìn)度條;或者當(dāng)在進(jìn)行一些比較 耗時的操作,需要等待一段較長的時間,這個時候如果沒有提示,用戶可能會以為程序Carsh或者手機死機 了,這樣會大大降低用戶體驗,所以在需要進(jìn)行耗時操作的地方,添加上進(jìn)度條,讓用戶知道當(dāng)前的程序 在執(zhí)行中,也可以直觀的告訴用戶當(dāng)前任務(wù)的執(zhí)行進(jìn)度等!使用進(jìn)度條可以給我?guī)磉@樣的便利! 好了,開始講解本節(jié)內(nèi)容~ 對了,ProgressBar官方API文檔:ProgressBar


1.常用屬性講解與基礎(chǔ)實例

從官方文檔,我們看到了這樣一個類關(guān)系圖:

ProgressBar繼承與View類,直接子類有AbsSeekBar和ContentLoadingProgressBar, 其中AbsSeekBar的子類有SeekBar和RatingBar,可見這二者也是基于ProgressBar實現(xiàn)的

常用屬性詳解:

  • android:max:進(jìn)度條的最大值
  • android:progress:進(jìn)度條已完成進(jìn)度值
  • android:progressDrawable:設(shè)置軌道對應(yīng)的Drawable對象
  • android:indeterminate:如果設(shè)置成true,則進(jìn)度條不精確顯示進(jìn)度
  • android:indeterminateDrawable:設(shè)置不顯示進(jìn)度的進(jìn)度條的Drawable對象
  • android:indeterminateDuration:設(shè)置不精確顯示進(jìn)度的持續(xù)時間
  • android:secondaryProgress:二級進(jìn)度條,類似于視頻播放的一條是當(dāng)前播放進(jìn)度,一條是緩沖進(jìn)度,前者通過progress屬性進(jìn)行設(shè)置!

對應(yīng)的再Java中我們可調(diào)用下述方法:

  • getMax():返回這個進(jìn)度條的范圍的上限
  • getProgress():返回進(jìn)度
  • getSecondaryProgress():返回次要進(jìn)度
  • incrementProgressBy(int diff):指定增加的進(jìn)度
  • isIndeterminate():指示進(jìn)度條是否在不確定模式下
  • setIndeterminate(boolean indeterminate):設(shè)置不確定模式下

接下來來看看系統(tǒng)提供的默認(rèn)的進(jìn)度條的例子吧!

系統(tǒng)默認(rèn)進(jìn)度條使用實例:

運行效果圖:

實現(xiàn)布局代碼:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!-- 系統(tǒng)提供的圓形進(jìn)度條,依次是大中小 -->

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

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

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <!--系統(tǒng)提供的水平進(jìn)度條-->
    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="18" />

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:indeterminate="true" />

</LinearLayout>

好吧,除了第二個能看,其他的就算了...系統(tǒng)提供的肯定是滿足不了我們的需求的! 下面我們就來講解下實際開發(fā)中我們對進(jìn)度條的處理!


2.使用動畫來替代圓形進(jìn)度條

第一個方案是,使用一套連續(xù)圖片,形成一個幀動畫,當(dāng)需要進(jìn)度圖的時候,讓動畫可見,不需要 的時候讓動畫不可見即可!而這個動畫,一般是使用AnimationDrawable來實現(xiàn)的!好的,我們來 定義一個AnimationDrawable文件:

PS:用到的圖片素材:進(jìn)度條圖片素材打包.zip

運行效果圖:

接著寫個布局文件,里面僅僅有一個ImageView即可,用于顯示進(jìn)度條,把src設(shè)置為上述drawable資源即可! 最后到MainActivity.java

public class MainActivity extends AppCompatActivity {

    private ImageView img_pgbar;
    private AnimationDrawable ad;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        img_pgbar = (ImageView) findViewById(R.id.img_pgbar);
        ad = (AnimationDrawable) img_pgbar.getDrawable();
        img_pgbar.postDelayed(new Runnable() {
            @Override
            public void run() {
                ad.start();
            }
        }, 100);
    }

}

這里只是寫了如何啟動動畫,剩下的就你自己來了哦~在需要顯示進(jìn)度條的時候,讓ImageView可見; 在不需要的時候讓他隱藏即可!另外其實Progressbar本身有一個indeterminateDrawable,只需把 這個參數(shù)設(shè)置成上述的動畫資源即可,但是進(jìn)度條條的圖案大小是不能直接修改的,需要Java代碼中 修改,如果你設(shè)置了寬高,而且這個寬高過大的時候,你會看到有多個進(jìn)度條...自己權(quán)衡下吧~


3.自定義圓形進(jìn)度條

相信你看完2會吐槽,臥槽,這么坑爹,拿個動畫來坑人,哈哈,實際開發(fā)中都這樣,當(dāng)然上述 這種情況只適用于不用顯示進(jìn)度的場合,如果要顯示進(jìn)度的場合就沒用處了,好吧,接下來看下 網(wǎng)上一個簡單的自定義圓形進(jìn)度條!代碼還是比較簡單,容易理解,又興趣可以看看,或者進(jìn)行相關(guān)擴(kuò)展~

運行效果圖:

實現(xiàn)代碼:

自定義View類:

/**
 * Created by Jay on 2015/8/5 0005.
 */
public class CirclePgBar extends View {

    private Paint mBackPaint;
    private Paint mFrontPaint;
    private Paint mTextPaint;
    private float mStrokeWidth = 50;
    private float mHalfStrokeWidth = mStrokeWidth / 2;
    private float mRadius = 200;
    private RectF mRect;
    private int mProgress = 0;
    //目標(biāo)值,想改多少就改多少
    private int mTargetProgress = 90;
    private int mMax = 100;
    private int mWidth;
    private int mHeight;

    public CirclePgBar(Context context) {
        super(context);
        init();
    }

    public CirclePgBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CirclePgBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    //完成相關(guān)參數(shù)初始化
    private void init() {
        mBackPaint = new Paint();
        mBackPaint.setColor(Color.WHITE);
        mBackPaint.setAntiAlias(true);
        mBackPaint.setStyle(Paint.Style.STROKE);
        mBackPaint.setStrokeWidth(mStrokeWidth);

        mFrontPaint = new Paint();
        mFrontPaint.setColor(Color.GREEN);
        mFrontPaint.setAntiAlias(true);
        mFrontPaint.setStyle(Paint.Style.STROKE);
        mFrontPaint.setStrokeWidth(mStrokeWidth);

        mTextPaint = new Paint();
        mTextPaint.setColor(Color.GREEN);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(80);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    //重寫測量大小的onMeasure方法和繪制View的核心方法onDraw()
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getRealSize(widthMeasureSpec);
        mHeight = getRealSize(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        initRect();
        float angle = mProgress / (float) mMax * 360;
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mBackPaint);
        canvas.drawArc(mRect, -90, angle, false, mFrontPaint);
        canvas.drawText(mProgress + "%", mWidth / 2 + mHalfStrokeWidth, mHeight / 2 + mHalfStrokeWidth, mTextPaint);
        if (mProgress < mTargetProgress) {
            mProgress += 1;
            invalidate();
        }

    }

    public int getRealSize(int measureSpec) {
        int result = 1;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) {
            //自己計算
            result = (int) (mRadius * 2 + mStrokeWidth);
        } else {
            result = size;
        }

        return result;
    }

    private void initRect() {
        if (mRect == null) {
            mRect = new RectF();
            int viewSize = (int) (mRadius * 2);
            int left = (mWidth - viewSize) / 2;
            int top = (mHeight - viewSize) / 2;
            int right = left + viewSize;
            int bottom = top + viewSize;
            mRect.set(left, top, right, bottom);
        }
    }

}

然后在布局文件中加上:

 <com.jay.progressbardemo.CirclePgBar
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

就是這么簡單~


本節(jié)小結(jié):

本節(jié)給大家介紹了Android中的常用控件:ProgressBar講解了基本用法,以及實際開發(fā)中 對于進(jìn)度條的兩種實現(xiàn)方法,第二個自定義進(jìn)度條可以自行完善,然后用到實際開發(fā)中~! 好的,本節(jié)就到這里,謝謝~


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號