我就不从canvas和paint开始说了,onMeasure,onLayout,onDraw这些方法的介绍和源码解析。网上一搜很多。一篇解释不清楚,多看几篇。话不多说了,先看看效果吧。
做成gif显示会有问题。我们先来分析一下需要什么数据、
1、需要一个进度
2、需要进度条基本信息,颜色,宽度,大小
3、需要字体大小,颜色
那么就来看看具体逻辑。
package com.example.administrator.myapplication.circle;
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.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import com.example.administrator.myapplication.R;
/**
* Created by ShuWen on 2017/6/10.
*/
public class CircleProgressBar extends View {
//进度条背景色
private int mCircleBgColor = Color.BLUE;
//进度条文字展示颜色
private int mTextColor = Color.GRAY;
//进度条宽度
private float mCircleWidth = 50;
//进度条颜色
private int mProgressColor = Color.GREEN;
//进度条展示文字大小
private float mTextSize = 50;
private int progress;
private int max = 100;
private Paint paint = new Paint();
public CircleProgressBar(Context context) {
super(context);
init(context,null);
}
public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
public void init(Context context,AttributeSet attrs){
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.CircleProgressBar);
mCircleBgColor = array.getColor(R.styleable.CircleProgressBar_mCircleBgColor,Color.BLUE);
mTextColor = array.getColor(R.styleable.CircleProgressBar_mTextColor,Color.GRAY);
mProgressColor = array.getColor(R.styleable.CircleProgressBar_mProgressColor,Color.GREEN);
mCircleWidth = array.getDimension(R.styleable.CircleProgressBar_mCircleWidth,50);
mTextSize = array.getDimension(R.styleable.CircleProgressBar_mTextSize,50);
array.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画背景
paint.setColor(mCircleBgColor);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeWidth(mCircleWidth);
int center = getWidth() / 2;
int radius = (int) (center - mCircleWidth / 2);
canvas.drawCircle(center,center,radius,paint);
//写文字
int percent = (int) (( progress / (float)max ) * 100);
String percentStr = percent + "%";
paint.setStrokeWidth(0);
paint.setColor(mTextColor);
paint.setTextSize(mTextSize);
Paint.FontMetricsInt fm = paint.getFontMetricsInt();
if (progress != 0){
canvas.drawText(percentStr,center - paint.measureText(percentStr) / 2,
center + (fm.bottom - fm.top) / 2 -fm.bottom,paint);
}
//画弧形
RectF oval = new RectF(center - radius,center - radius,center + radius,center + radius);
paint.setStrokeWidth(mCircleWidth);
paint.setColor(mProgressColor);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawArc(oval,0,360 * progress/max,false,paint);
}
//设置进度条
public void setProgress(int progress){
if (progress > max){
progress = max;
}
if (progress <= max){
this.progress = progress;
postInvalidate();
}
}
}
需要自定义的属性。
<resources>
<declare-styleable name="CircleProgressBar">
<attr name="mCircleBgColor" format="color"/>
<attr name="mTextColor" format="color"/>
<attr name="mCircleWidth" format="dimension"/>
<attr name="mTextSize" format="dimension"/>
<attr name="mProgressColor" format="color"/>
declare-styleable>
resources>
详细布局
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.administrator.myapplication.MainActivity">
<com.example.administrator.myapplication.circle.CircleProgressBar
android:id="@+id/progressBar"
android:layout_width="100dp"
android:layout_height="100dp"
app:mCircleBgColor="#ff00ff"
app:mCircleWidth="10dp"
app:mProgressColor="#00ff00"
app:mTextColor="#000"
app:mTextSize="20dp"
/>
RelativeLayout>
ManActivity,开启一个线程,休眠100ms,重新设置进度。
package com.example.administrator.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.example.administrator.myapplication.circle.CircleProgressBar;
import com.example.administrator.myapplication.flow.WaterFallLayout;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
WaterFallLayout waterfall;
private static int IMG_COUNT = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CircleProgressBar progressBar = (CircleProgressBar) findViewById(R.id.progressBar);
progressBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
int progress = 0;
while (progress <= 100){
progress += 2;
progressBar.setProgress(progress);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
}
圆形进度条呢,网上其实很多。写的也很详细,我这里只是做一个学习笔记。