編輯:Android資訊
在上一篇博文中,我們給大家介紹了Android自定義控件系列的基礎篇。鏈接:http://www.codeceo.com/article/android-basic.html
這一篇博文中,我們將在基礎篇的基礎上,再通過重寫ondraw()方法和自定義屬性實現圓形進度條,效果如圖所示:


1、 編寫自定義組件MyCircleProgress擴展View
public class MyCircleProgress extends View {
…
}
2、 在MyCircleProgress類中,定制屬性
public int progress = 0;//進度實際值,當前進度
/**
* 自定義控件屬性,可靈活的設置圓形進度條的大小、顏色、類型等
*/
private int mR;//圓半徑,決定圓大小
private int bgColor;//圓或弧的背景顏色
private int fgColor;//圓或弧的前景顏色,即繪制時的顏色
private int drawStyle; //繪制類型 FILL畫圓形進度條,STROKE繪制弧形進度條
private int strokeWidth;//STROKE繪制弧形的弧線的寬度
private int max;//最大值,設置進度的最大值
/**
* 設置進度,此為線程安全控件,由於考慮多線的問題,需要同步
*/
public synchronized void setProgress(int progress) {
if(progress<0){
progress=0;
}else if(progress>max){
progress=max;
}else{
this.progress = progress;
}
}
public int getMax() {
return max; }
3、 為定制的屬性編寫attrs.xml資源,該資源文件放在res/values目錄下,內容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressBar">
<attr name="bgColor" format="color"/>
<attr name="fgColor" format="color"/>
<attr name="r" format="integer"/>
<attr name="strokeWidth" format="integer"/>
<attr name="drawStyle">
<enum name="STROKE" value="0"></enum>
<enum name="FILL" value="1"></enum>
</attr>
<attr name="max" format="integer"/>
</declare-styleable>
</resources>
4、 在MyCircleProgress類中定義構造函數,初始化屬性
private void initProperty(AttributeSet attrs){
TypedArray tArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
mR=tArray.getInteger(R.styleable.CircleProgressBar_r,10);
bgColor=tArray.getColor(R.styleable.CircleProgressBar_bgColor, Color.GRAY);
fgColor=tArray.getColor(R.styleable.CircleProgressBar_fgColor, Color.RED);
drawStyle=tArray.getInt(R.styleable.CircleProgressBar_drawStyle, 0);
strokeWidth=tArray.getInteger(R.styleable.CircleProgressBar_strokeWidth, 10);
max=tArray.getInteger(R.styleable.CircleProgressBar_max, 100);
}
public MyCircleProgress(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.paint = new Paint();
this.paint.setAntiAlias(true); // 消除鋸齒
this.paint.setStyle(Style.STROKE); // 繪制空心圓或 空心矩形
initProperty(attrs);
}
5、 在MainActivity中布局文件中添加MyCircleProgress組件,如下所示
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/com.jereh.mydrawcircleprogress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
>
<com.jereh.views.MyCircleProgress
android:id="@+id/MyCircleProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:r="45"
app:strokeWidth="10"
app:bgColor="#cccccc"
app:fgColor="#ff0000"
app:draw
app:max="50"
/>
</RelativeLayout>
6、 自定義組件MyCircleProgress中重寫onDraw方法:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int center = getWidth() / 2; // 圓心位置
this.paint.setColor(bgColor);
this.paint.setStrokeWidth(strokeWidth);
canvas.drawCircle(center, center, mR, this.paint);
// 繪制圓環
this.paint.setColor(fgColor);
if(drawStyle==0){
this.paint.setStyle(Style.STROKE);
opt=false;
}else{
this.paint.setStyle(Style.FILL);
opt=true;
}
int top = (center - mR);
int bottom = (center + mR);
RectF oval = new RectF(top, top, bottom, bottom);
canvas.drawArc(oval, 270, 360*progress/max, opt, paint);
}
7、編寫MainActivity
public class MainActivity extends Activity {
private MyCircleProgress progressView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressView = (MyCircleProgress) findViewById(R.id.MyCircleProgress);
new ProgressAnimation().execute();
}
class ProgressAnimation extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
//進度值不斷的變化
for (int i = 0; i < progressView.getMax(); i++) {
try {
publishProgress(i);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新進度值
progressView.setProgress(values[0]);
progressView.invalidate();
super.onProgressUpdate(values);
}
}
}
Android應用Loaders全面詳解及源碼淺析
1 背景 在Android中任何耗時的操作都不能放在UI主線程中,所以耗時的操作都需要使用異步實現。同樣的,在ContentProvider中也可能存在耗時操作,
Eclipse中Android公共庫的正確建立及調用方法
之前一直頭痛於沒有辦法在多個程序中共享資源,用作公共類庫的方法也是使用的導出jar再導入的辦法,現在終於初步搞明白了,可算解脫了~,分享出來。 建立公共庫 首先建
Android錯誤解決方法集錦
1 android java.net.UnknownHostException: Unable to resolve host “…
Android Activity 啟動模式的功能驗證
之前一直都是看別人寫的啟動模式,發現網上大多數的內容都是抄襲來抄襲去,直到最近看了開發藝術這本書,發現之前對啟動模式的理解過於簡單,很多東西都沒有考慮到,為了加深