Android 自定義View製作隨時間增長的平滑進度條

Android 自定義View製作隨時間增長的平滑進度條


在做一個短視頻錄製的項目中,需要一個平滑增加的進度條,開始的想法是做系統自帶的進度條然後把最大進度設置到非常大實現,但實際上有點達不到效果,所以就用自定義View的方式來實現。


基本思路:

       利用View自帶的invalidate()函數,重複調用onDraw()函數來進行進度條的變化。


在onDraw()中利用

System.currentTimeMillis();
獲取上一次調用onDraw的時間和這次時間得出一個時間差,根據時間差利用

canvas.drawRect(0,0,countWidth,getMeasuredHeight(),progressPaint);
重新繪製一個長度的矩形,作爲進度條的進度


源碼:

package com.text.nickey.progressviewactivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

/**
 * Created by nickey on 2016/3/21.
 */
public class MyProgressView extends View {

    private Context mContext;
    private WindowManager mWindowManager;

    public MyProgressView(Context context) {
        this(context, null);
    }

    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
    }
    private int millisecond = 1000;
    private float maxProgressSize = 60 * millisecond;//總進度是60
    private float eachProgressWidth = 0;
    private Paint progressPaint;

    private void init(){
        //設置每一刻度的寬度
        DisplayMetrics dm = new DisplayMetrics();
        mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        mWindowManager.getDefaultDisplay().getMetrics(dm);
        eachProgressWidth = dm.widthPixels / (maxProgressSize * 1.0f);
        //進度條的背景顏色
        setBackgroundColor(Color.parseColor("#19000000"));
        //進度條的前景顏色,畫筆
        progressPaint = new Paint();
        progressPaint.setStyle(Paint.Style.FILL);
        progressPaint.setColor(Color.parseColor("#ffffff"));

    }
    private long initTime = -1;//上一次刷新完成後的時間
    private boolean isStart = false;
    private float countWidth = 0;//進度條進度的進程,每次調用invalidate()都刷新一次
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        if (!isStart){
            canvas.drawRect(0,0,countWidth,getMeasuredHeight(),progressPaint);
            return;
        }
        if (initTime == -1){
            initTime =  System.currentTimeMillis();
            canvas.drawRect(0,0,countWidth,getMeasuredHeight(),progressPaint);
            invalidate();
            return;
        }
        //這次刷新的時間,用於與上一次刷新完成的時間作差得出進度條需要增加的進度
        long thisTime = System.currentTimeMillis();
        countWidth += eachProgressWidth * (thisTime - initTime) * 1.0f;
        if (countWidth > getMeasuredWidth()){
            countWidth = getMeasuredWidth();
        }
        Log.d("MyProgressView", "onDraw() called with: " + "countWidth = [" + countWidth + "]");
        canvas.drawRect(0,0,countWidth,getMeasuredHeight(),progressPaint);

        //如果都了最大長度,就不再調用invalidate();了
        if (countWidth < getMeasuredWidth()  && isStart){
            initTime = System.currentTimeMillis();
            invalidate();
        }else{
            countWidth = 0;
            initTime = -1;
            isStart = false;
        }


    }
    //開始或暫停進度條進度刷新
    public void setIsStart(boolean isStart) {
        if (isStart == this.isStart)
            return;
        this.isStart = isStart;
        if (isStart) {
            initTime = -1;
            invalidate();
        }
    }
    //重置進度條
    public void reset() {
        countWidth = 0;
        initTime = -1;
        isStart = false;
        invalidate();
    }
}



源碼下載地址:http://download.csdn.net/detail/nickey_1314/9475570

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章