android之自定義View和ViewGroup(四)(代碼篇,實現圓形進度條)

好久不寫博客,最近沒任務就來寫寫博客,今天就寫個簡單的自定義圓形進度條的實現,最終效果如下:


好了,我們首先分析一下如果是你做這種效果需要哪些步驟呢?考慮幾秒再看下面的。別偷懶。


你思考了麼?這麼快就來看步驟了,太懶了吧!

其實很簡單,3個步驟,1.畫中間綠色的圓形;2.畫外面藍色的進度(其實是一個扇形);3.畫進度(圖中的數字1%-99%、完成),畫的綠色圓形將藍色的扇形覆蓋住,就是上圖的效果了,然後慢慢改變藍色扇形的角度就行了。具體實現步驟如下圖:


是不是很簡單?當然簡單!

那麼開始寫具體實現代碼!

首先自定義一個類繼承自View,實現構造方法初始化:扇形,綠色圓形,字,這三個屬性所需的畫筆(我用了三個畫筆是爲了區分大家方便看,當然也可以只用一個畫筆就行了)

package com.custom.my.widget;

public class CircleProgressBar extends View {
	
	private Context context;
	private int height,width;  //自定義控件的寬高
	private float progress;  //進度

	private Paint paint;  //藍色扇形所需的畫筆
	private Paint bkPaint;  //綠色圓形所需的畫筆
	private Paint tvPaint;  //圓裏面的進度字所需的畫筆
	private Rect mBound;  //用於獲取字體的大小

	public CircleProgressBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		this.paint = new Paint();
		this.bkPaint = new Paint();
		this.tvPaint = new Paint();
		this.mBound = new Rect();
		init();
	}

	private void init(){
		paint.setStyle(Style.FILL);
		paint.setColor(Color.parseColor("#50A3FE"));
		paint.setAntiAlias(true);

		bkPaint.setStyle(Style.FILL);
		bkPaint.setColor(Color.parseColor("#00ff00"));
		bkPaint.setAntiAlias(true);

		tvPaint.setColor(Color.parseColor("#ffffff"));
		tvPaint.setTextSize(15);
	}

}
畫筆等屬性初始化完成後,我們需要獲取我們設置的寬高(這個圓形進度條的整體寬高),而我們獲取View寬高的地方是重寫View的onMeasure方法:

//獲取當前控件的高度和寬度,單位是像素
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		height = MeasureSpec.getSize(heightMeasureSpec);
		width = MeasureSpec.getSize(widthMeasureSpec);
	}
獲取到了寬高後我們就可以開始畫了,在CircleProgressBar 的onDraw方法裏面畫扇形,圓形,字。

private float set2Degree(float sendFt){   //將進度的數值變爲弧度數值,進度100,弧度有360,所以比例是3.6
		return sendFt*3.6f;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(width*height==0){
			return;
		}
		canvas.drawArc(new RectF(0, 0, width, height), 270, set2Degree(progress), true, paint);  //畫藍色扇形
		canvas.drawCircle(width / 2, height / 2, width / 2 - 5, bkPaint);  //畫綠色圓形,半徑比藍色扇形的小5px
		if(progress < 100){   //進度沒達到100%時顯示進度
			String strPro = String.valueOf((int)progress)+"%";
			tvPaint.getTextBounds(strPro,0,strPro.length(),mBound);
			canvas.drawText(strPro,width/2 - mBound.width()/2,height/2 + mBound.height()/2,tvPaint);
		}else{  //達到100%後顯示完成
			String text = "完成";
			tvPaint.getTextBounds(text,0,text.length(),mBound);
			canvas.drawText(text,width/2 - mBound.width()/2,height/2 + mBound.height()/2,tvPaint);
		}
	}
當然畫了後我們要實時更新弧度,所以我們在CircleProgressBar 裏面加個public方法來實時更新進度。

public void setProgress(float progress){
		this.progress = progress;
		postInvalidate();
	}
當進度發生改變後調用改方法修改進度即可。使用用例如下:

xml佈局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.custom.my.activity.CircleProgressAcitivity">

    <com.custom.my.widget.CircleProgressBar
        android:id="@+id/circle_progress"
        android:layout_centerInParent="true"
        android:layout_width="65dp"
        android:layout_height="65dp" />

</RelativeLayout>
Activity中如下,爲了模擬進度,我們使用handler來不停地更新進度:

public class CircleProgressAcitivity extends AppCompatActivity {

    private CircleProgressBar circleProgressBar;
    private float progress = 0;

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

        circleProgressBar = (CircleProgressBar) findViewById(R.id.circle_progress);
        handler.sendEmptyMessageDelayed(1,100);
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == 1){
                if(progress <= 99){
                    ++progress;
                    circleProgressBar.setProgress(progress);  //更新進度條
                    this.sendEmptyMessageDelayed(1, 100);
                }
            }
        }
    };
}

完成了,整個思路很簡單,代碼也很簡單,當然如果想自定義字體的顏色,字體大小等,可以結合之前我寫的那個自定義條形進度條的那篇博客http://blog.csdn.net/gsw333/article/details/50803313就行,當然如果覺得太醜也可以把中間的綠色換成一個beautiful圖片就行了,反正做法都是一樣。


最後最後最後!!!!!!!!!!如果你覺得不錯幫我頂一頂!!!!!!!!!如果覺得不好,請給我的辛苦碼字頂一頂!!!!!!!!!



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