一:动画效果:
二:源码:
(1)res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyView"> <attr name="roundColor" format="color"/> <attr name="roundProgressColor" format="color"/> <attr name="roundWidth" format="dimension"></attr> <attr name="textColor" format="color"/> <attr name="textSize" format="dimension"/> <attr name="max" format="integer"></attr> <attr name="textIsDisplayable" format="boolean"></attr> <attr name="style"> <enum name="TIME_TICKER" value="0"></enum> <enum name="PROGRESS" value="1"></enum> </attr> </declare-styleable> </resources>(2)myview.java:
public class MyView extends View { private final static String TAG = "RoundProgressBar01"; private Paint paint; private int roundColor; private int roundProgressColor; private int textColor; private float textSize; private float roundWidth; private int max; private int progress; private boolean textIsDisplayable; private int style; public static final int STROKE = 0; public static final int FILL = 1; public MyView(Context context) { super(context); init(); } public MyView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); TypedArray mTypedArray = context.obtainStyledAttributes(attrs,R.styleable.MyView); roundColor = mTypedArray.getColor(R.styleable.MyView_roundColor, Color.RED); roundProgressColor = mTypedArray.getColor(R.styleable.MyView_roundProgressColor, Color.GREEN); textColor = mTypedArray.getColor(R.styleable.MyView_textColor, Color.GREEN); textSize = mTypedArray.getDimension(R.styleable.MyView_textSize, 15); roundWidth = mTypedArray.getDimension(R.styleable.MyView_roundWidth, 20); max = mTypedArray.getInteger(R.styleable.MyView_max, 100); textIsDisplayable = mTypedArray.getBoolean(R.styleable.MyView_textIsDisplayable, true); style = mTypedArray.getInt(R.styleable.MyView_style, 0); mTypedArray.recycle(); } public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void init(){ paint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centre = getWidth()/2; //获取圆心的x坐标 int radius = (int) (centre - roundWidth/2); //圆环的半径 paint.setColor(roundColor); //设置圆环的颜色 paint.setStyle(Paint.Style.STROKE); //设置空心 paint.setStrokeWidth(roundWidth); //设置圆环的宽度 paint.setAntiAlias(true); //消除锯齿 canvas.drawCircle(centre, centre, radius, paint); //画出圆环 /** * 画进度百分比 */ paint.setStrokeWidth(0); paint.setColor(textColor); paint.setTextSize(textSize); paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体 //中间的进度百分比,先转换成float在进行除法运算,不然都为0 int percent = (int)(((float)progress / (float)max) * 100); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间 float textWidth = paint.measureText(percent + "%"); Log.i(TAG, "onDraw:"+"textIsDisplayable:"+textIsDisplayable+"--percent:"+percent+"--style == STROKE:"+(style == STROKE)); //if(textIsDisplayable && percent != 0 && style == STROKE){ if(textIsDisplayable && style == STROKE){ //画出进度百分比 canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint); } /** * 画圆弧 ,画圆环的进度 */ //设置进度是实心还是空心 paint.setStrokeWidth(roundWidth); //设置圆环的宽度 paint.setColor(roundProgressColor); //设置进度的颜色 //用于定义的圆弧的形状和大小的界限 RectF oval = new RectF(centre - radius, centre - radius, centre+ radius, centre + radius); switch (style) { case STROKE:{ paint.setStyle(Paint.Style.STROKE); //根据进度画圆弧 canvas.drawArc(oval, 0, 360 * progress / max, false, paint); break; } case FILL:{ paint.setStyle(Paint.Style.FILL_AND_STROKE); if(progress !=0) //根据进度画圆弧 canvas.drawArc(oval, 0, 360 * progress / max, true, paint); break; } } } public synchronized int getMax() { return max; } public synchronized void setMax(int max) { if(max < 0){ throw new IllegalArgumentException("max not less than 0"); } this.max = max; } public synchronized int getProgress() { return 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 synchronized void setStyle(int style){ this.style = style; } //改变颜色的方法 public void setMyColor(int color){ roundColor = color; invalidate(); } }(3):MainActivity.java:
private MyView roundProgressBar_01 = null; private int TIME_TICKER = 0; private int progress = 0; private final int UPDATE_UI_01 = 1; private boolean flag; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch(msg.what){ case UPDATE_UI_01: progress++; if(progress > 100){ progress = 0; } handler.sendEmptyMessageDelayed(UPDATE_UI_01, 300); updateUIRoundProgressBar_01(progress); break; } } }; private Button start,chongzhi,change; private MyView myView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到控件 start = (Button) findViewById(R.id.start); chongzhi = (Button) findViewById(R.id.chongzhi); change = (Button) findViewById(R.id.change); myView = (MyView) findViewById(R.id.roundProgressBar_01); init(); //开始的点击事件 start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessageDelayed(UPDATE_UI_01, 300); } }); //重置的点击事件 chongzhi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { progress = 0; } }); //改变颜色的点击事件 change.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(flag){ myView.setMyColor(Color.RED); flag = false; }else { myView.setMyColor(Color.BLUE); flag = true; } } }); } private void init() { // TODO Auto-generated method stub roundProgressBar_01 = (MyView) findViewById(R.id.roundProgressBar_01); roundProgressBar_01.setStyle(TIME_TICKER); roundProgressBar_01.setProgress(1); progress = 1; } private void updateUIRoundProgressBar_01(int progress){ roundProgressBar_01.setProgress(progress); } }(4)布局文件:res/layout/activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:custom_progress="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.bwie.lk.MainActivity"> <Button android:id="@+id/change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="改变外层圆环颜色"/> <com.bwie.lk.MyView android:layout_gravity="center" android:id="@+id/roundProgressBar_01" android:layout_width="80dip" android:layout_height="80dip" custom_progress:roundColor="#3300d1d1" custom_progress:roundProgressColor="@android:color/black" custom_progress:textColor="#9A32CD" custom_progress:textIsDisplayable="true" custom_progress:roundWidth="10dip" custom_progress:textSize="18sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="100dp"> <Button android:id="@+id/start" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="开始"/> <Button android:id="@+id/chongzhi" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="重置"/> </LinearLayout> </LinearLayout>