1.首先定义属性文件:
《attr》,此文件定义的属性可在xml中定义相关属性,以及代码中定义属性
2.定义继承view的progressbar,其代码参考系统progressbar的源码进行修改,以减少自定义控件的额<declare-styleable name="RoundProgressBar"> <!-- 设置最外层圆环或扇形颜色颜色--> <attr name="roundColor" format="color"/> <!-- 设置第二层(中间层)圆环或扇形颜色颜色--> <attr name="roundCenterColor" format="color"/> <!-- 设置进度条颜色--> <attr name="roundProgressColor" format="color"/> <!-- 设置进度条百分比文字大小颜色--> <attr name="textColor" format="color" /> <!-- 设置进度条功能文字大小颜色--> <attr name="buttonTextColor" format="color" /> <attr name="roundWidth" format="dimension"></attr> <!-- 设置进度条百分比文字大小颜色--> <attr name="textSize" format="dimension" /> <!-- 设置进度条功能文字大小颜色--> <attr name="buttonTextSize" format="dimension" /> <!-- 中心点偏移量--> <attr name="centeroffset" format="integer" /> <!-- 最外层圆环偏移量--> <attr name="outermostLayerCircleoffset" format="integer" /> <!-- 线的宽度--> <attr name="progresslineWidth" format="integer" /> <attr name="max" format="integer"></attr> <attr name="textIsDisplayable" format="boolean"></attr> <attr name="buttonText" format="string"></attr> <attr name="progressStyle"> <enum name="STROKE" value="0"></enum> <enum name="FILL" value="1"></enum> </attr> </declare-styleable>
3.在项目中的使用package com.pinban.app.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.google.zxing.common.detector.MathUtils; import com.lidroid.xutils.util.LogUtils; import com.pinban.app.R; /** * Created by wesley.wu on 2016/1/30. * 带进度的进度条,线程安全的View,可直接在线程中更新进度 */ public class RoundProgressBar extends View { /** * 画笔对象的引用 */ private Paint paint; /** * 圆环的颜色 */ private int roundColor; /** * 圆环进度的颜色 */ private int roundProgressColor; /** * 中间进度百分比的字符串的颜色 */ private int textColor; /** * 中间圆环的颜色*/ private int roundCenterColor; /** * 功能字体大小*/ private int buttonTextColor; /** * 中间进度百分比的字符串的字体 */ private float textSize; /** * 功能字体大小*/ private float buttonTextSize; /** * 圆环的宽度 */ private float roundWidth; /** * 最大进度 */ private int max; /** * 当前进度 */ private int progress; /** * 是否显示中间的进度 */ private boolean textIsDisplayable; /** * 进度的风格,实心或者空心 */ private int style; /*** * 默认颜色 */ private int defultColor = getResources().getColor(R.color.pinban_title_light_blue_3ECCC2); /** * 进度条文字说明*/ private String buttonText; /** * 中心点偏移量*/ private int centeroffset; /** * 最外层圆环偏移量*/ private int outermostLayerCircleoffset; /** * 线宽*/ private int progresslineWidth; public static final int STROKE = 0; public static final int FILL = 1; public RoundProgressBar(Context context) { this(context, null); } public RoundProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); paint = new Paint(); TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar); //获取自定义属性和默认值 roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, defultColor); roundCenterColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundCenterColor,Color.WHITE); roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, defultColor); textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, defultColor); buttonTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_buttonTextColor, defultColor); textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15); buttonTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_buttonTextSize,15); roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5); max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100); textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true); style = mTypedArray.getInt(R.styleable.RoundProgressBar_progressStyle, 0); buttonText = mTypedArray.getString(R.styleable.RoundProgressBar_buttonText); centeroffset = mTypedArray.getInt(R.styleable.RoundProgressBar_centeroffset,10); outermostLayerCircleoffset = mTypedArray.getInt(R.styleable.RoundProgressBar_outermostLayerCircleoffset,8); progresslineWidth = mTypedArray.getInt(R.styleable.RoundProgressBar_progresslineWidth,8); mTypedArray.recycle(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 画自定义C字型图形*/ int centreX = getWidth()/2-centeroffset; //获取圆心的x坐标 int centreY = getHeight()/2-centeroffset; //获取圆心的x坐标 int radius = (int) (centreX - (roundWidth+outermostLayerCircleoffset)/2); //圆环的半径 int little_radius = (int) (centreX - roundWidth-outermostLayerCircleoffset); paint.setColor(roundColor); //设置圆环的颜色 paint.setStyle(Paint.Style.STROKE); //设置空心 paint.setStrokeWidth(roundWidth+outermostLayerCircleoffset); //设置圆环的宽度 RectF oval0 = new RectF(centreX - radius, centreX - radius, centreX + radius, centreX + radius); paint.setAntiAlias(true); //消除锯齿 //canvas.drawCircle(centreX, centreX, radius, paint); //画出圆环 canvas.drawArc(oval0, 90, 300, false, paint); //画圆弧 paint.setColor(roundCenterColor); //设置圆环的颜色 paint.setStyle(Paint.Style.STROKE); //设置空心 paint.setStrokeWidth(roundWidth); //设置圆环的宽度 RectF oval1 = new RectF(centreX - radius, centreX - radius, centreX + radius, centreX + radius); paint.setAntiAlias(true); //消除锯齿 //canvas.drawCircle(centreX, centreX, radius, paint); //画出圆环 canvas.drawArc(oval1, 90, 300, false, paint); //画圆弧 //canvas.drawLine((float) centreX,(float)centreX,(float)centreX,(float)centreX,paint); paint.setColor(roundColor); paint.setStrokeWidth(progresslineWidth); canvas.drawLine((float) (centreX + little_radius*Math.cos(Math.toRadians(30))), (float) (centreX + little_radius*Math.sin(Math.toRadians(30))), (float) (centreX + centreX*Math.cos(Math.toRadians(30))), (float) (centreX + centreX*Math.sin(Math.toRadians(30))),paint); Log.i("wesley.wu", "roundWidth:"+roundWidth+"centreX:"+centreX + " centreY:"+centreY+" radius:"+radius +"X:坐标"+(float) ( little_radius*Math.cos(Math.toRadians(30))) +"Y:坐标"+(float) ( little_radius*Math.sin(Math.toRadians(30)))); paint.setStrokeWidth(progresslineWidth); canvas.drawLine((float) centreX,(float) centreX+little_radius,(float) centreX,(float)2*centreX,paint); /** * 画进度百分比 */ paint.setStrokeWidth(0); paint.setColor(textColor); paint.setTextSize(textSize); paint.setTypeface(Typeface.DEFAULT); //设置字体 int percent = (int)(((float)progress / (float)max) * 100); //中间的进度百分比,先转换成float在进行除法运算,不然都为0 float textWidth = paint.measureText(percent + "%"); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间 if(textIsDisplayable && percent != 0 && style == STROKE){ canvas.drawText(percent + "%", centreX - textWidth / 2, centreX + textSize/2, paint); //画出进度百分比 } canvas.drawText(buttonText,centreX+outermostLayerCircleoffset,2*centreX-textSize/2,paint); /** * 画圆弧 ,画圆环的进度 */ //设置进度是实心还是空心 paint.setStrokeWidth(roundWidth); //设置圆环的宽度 paint.setColor(roundProgressColor); //设置进度的颜色 RectF oval = new RectF(centreX - radius, centreX - radius, centreX + radius, centreX + radius); //用于定义的圆弧的形状和大小的界限 switch (style) { case STROKE:{ paint.setStyle(Paint.Style.STROKE); canvas.drawArc(oval, 90, 360 * progress / max, false, paint); //根据进度画圆弧 break; } case FILL:{ paint.setStyle(Paint.Style.FILL_AND_STROKE); if(progress !=0) canvas.drawArc(oval, 90, 360 * progress / max, true, paint); //根据进度画圆弧 break; } } } /** * 设置默认进度条的单色显示*/ public void setMonochromatic(int defultColor){ this.roundColor = defultColor; this.roundProgressColor = defultColor; this.textColor = defultColor; this.buttonTextColor = defultColor; } public Paint getPaint() { return paint; } public void setPaint(Paint paint) { this.paint = paint; } public int getProgresslineWidth() { return progresslineWidth; } public void setProgresslineWidth(int progresslineWidth) { this.progresslineWidth = progresslineWidth; } public int getButtonTextColor() { return buttonTextColor; } public void setButtonTextColor(int buttonTextColor) { this.buttonTextColor = buttonTextColor; } public int getRoundCenterColor() { return roundCenterColor; } public void setRoundCenterColor(int roundCenterColor) { this.roundCenterColor = roundCenterColor; } public float getButtonTextSize() { return buttonTextSize; } public void setButtonTextSize(float buttonTextSize) { this.buttonTextSize = buttonTextSize; } public int getDefultColor() { return defultColor; } public void setDefultColor(int defultColor) { this.defultColor = defultColor; } public int getCenteroffset() { return centeroffset; } public void setCenteroffset(int centeroffset) { this.centeroffset = centeroffset; } public int getOutermostLayerCircleoffset() { return outermostLayerCircleoffset; } public void setOutermostLayerCircleoffset(int outermostLayerCircleoffset) { this.outermostLayerCircleoffset = outermostLayerCircleoffset; } public synchronized int getMax() { return max; } /** * 设置进度的最大值 * @param max */ public synchronized void setMax(int max) { if(max < 0){ throw new IllegalArgumentException("max not less than 0"); } this.max = max; } /** * 获取进度.需要同步 * @return */ public synchronized int getProgress() { return progress; } /** * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 * 刷新界面调用postInvalidate()能在非UI线程刷新 * @param progress */ public synchronized void setProgress(int progress) { if(progress < 0){ throw new IllegalArgumentException("progress not less than 0"); } if(progress > max){ progress = max; } if(progress <= max){ this.progress = progress; postInvalidate(); } } public int getCricleColor() { return roundColor; } public void setCricleColor(int cricleColor) { this.roundColor = cricleColor; } public int getCricleProgressColor() { return roundProgressColor; } public void setCricleProgressColor(int cricleProgressColor) { this.roundProgressColor = cricleProgressColor; } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { this.textColor = textColor; } public float getTextSize() { return textSize; } public void setTextSize(float textSize) { this.textSize = textSize; } public float getRoundWidth() { return roundWidth; } public void setRoundWidth(float roundWidth) { this.roundWidth = roundWidth; } public int getRoundColor() { return roundColor; } public void setRoundColor(int roundColor) { this.roundColor = roundColor; } public int getRoundProgressColor() { return roundProgressColor; } public void setRoundProgressColor(int roundProgressColor) { this.roundProgressColor = roundProgressColor; } public boolean isTextIsDisplayable() { return textIsDisplayable; } public void setTextIsDisplayable(boolean textIsDisplayable) { this.textIsDisplayable = textIsDisplayable; } public int getStyle() { return style; } public void setStyle(int style) { this.style = style; } public String getButtonText() { return buttonText; } public void setButtonText(String buttonText) { this.buttonText = buttonText; } public static int getSTROKE() { return STROKE; } public static int getFILL() { return FILL; } }
(1)定义先关控件及属性
@ViewInject(R.id.roundProgressBar1) private RoundProgressBar roundProgressBar1; final private MyThread nth =new MyThread(0); //线程终端标志位,下一步按钮进度条显示使用线程进行数据的填充 private Boolean threadInterrputFlag = true;(2)开启线程nth.start();
(3)定义开启写进度的线程(5)注意在activity周期、返回键,自定义返回图标监听中定义关闭线程的关键量,/** * 下一步按钮的线程定义*/ class MyThread extends Thread implements Runnable{ int progress; public MyThread(int progress) { this.progress = progress; } @Override public void run() { go(this.isInterrupted(),progress); } } private synchronized void go(boolean interrupted, int progress){ for (int i = 0;i < 360;i++){ if (!threadInterrputFlag) break; progress += 1; System.out.println(progress); roundProgressBar1.setProgress(progress); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } if (i==200){ i = 0; progress = 0; } } }
@Override protected void onResume() { super.onResume(); threadInterrputFlag = true; } @Override protected void onPause() { super.onPause(); threadInterrputFlag = false; } @Override protected void onDestroy() { super.onDestroy(); threadInterrputFlag = false; }
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { threadInterrputFlag = false; return true; } return super.onKeyDown(keyCode, event); }
4.xml定义命名控件xmlns:roundProgressBar="http://schemas.android.com/apk/res-auto"<pre name="code" class="java"> <com.pinban.app.widget.RoundProgressBar android:id="@+id/roundProgressBar1" android:layout_width="100dp" android:layout_height="100dp" android:layout_alignParentBottom="true" android:layout_marginBottom="78dp" roundProgressBar:buttonText="下一步" roundProgressBar:roundColor="@color/pinban_title_light_blue_3ECCC2" roundProgressBar:roundProgressColor="@android:color/holo_red_dark" roundProgressBar:textColor="#9A32CD" roundProgressBar:textIsDisplayable="false" roundProgressBar:roundWidth="28dp" roundProgressBar:textSize="18sp" android:layout_marginLeft="100dp"/>