-
目录结构
-
核心代码CicleProgressView.java
public class CircleProgressView extends View {
/**
* 背景颜色
*/
private int backgroundColor;
/**
* 前景颜色
*/
private int foregroundColor;
/**
* 进度条颜色
*/
private int progressColor;
/**
* 字体颜色
*/
private int fontColor;
/**
* 当前进度
*/
private int currentProgress = 0;
/**
* 最大进度
*/
private int maxProgress;
/**
* 画笔
*/
private Paint mPaint = new Paint();
/**
* 半径长
*/
private int mRadius;
/**
* 进度宽
*/
private int progressWidth;
/**
* 字体大小
*/
private int textSize;
/**
* 回调监听
*/
private ProgressedListener listener;
public CircleProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
backgroundColor = a.getColor(R.styleable.CircleProgressView_circleprogress_backgroundcolor, Color.WHITE);
foregroundColor = a.getColor(R.styleable.CircleProgressView_circleprogress_foregroundcolor, Color.WHITE);
progressColor = a.getColor(R.styleable.CircleProgressView_circleprogress_progresscolor, Color.BLUE);
fontColor = a.getColor(R.styleable.CircleProgressView_circleprogress_fontcolor, Color.BLUE);
maxProgress = a.getInteger(R.styleable.CircleProgressView_circleprogress_maxprogress, 100);
progressWidth = a.getInteger(R.styleable.CircleProgressView_circleprogress_width, 10);
textSize = a.getInteger(R.styleable.CircleProgressView_circleprogress_textsize, 10);
a.recycle();//释放资源
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
// int widthSize = MeasureSpec.getSize(widthMeasureSpec);
// int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(200, 200);
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(heightMeasureSpec, heightMeasureSpec);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w > h) {
mRadius = h / 2;
} else {
mRadius = w / 2;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(backgroundColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mPaint);//画最下边的圆
mPaint.setColor(progressColor);
canvas.drawArc(getWidth() / 2 - mRadius,
getHeight() / 2 - mRadius,
getWidth() / 2 + mRadius,
getHeight() / 2 + mRadius,
-90,
360 * (((float) currentProgress) / maxProgress),
true,
mPaint);//画扇形
mPaint.setColor(foregroundColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2,
mRadius - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, progressWidth, getResources().getDisplayMetrics()),
mPaint);//画中心圆
mPaint.setColor(fontColor);
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, textSize, getResources().getDisplayMetrics()));
String text = currentProgress + "%";
canvas.drawText(text,
getWidth() / 2 - mPaint.measureText(text) / 2,
getHeight() / 2 + mPaint.measureText("%") / 2,
mPaint);//画文字
}
/**
* 设置当前进度
*
* @param currentProgress
*/
public void setCurrentProgress(int currentProgress) {
if (currentProgress <= 0) {
currentProgress = 0;
if (listener != null) {
listener.startLoad();
}
}
if (currentProgress >= maxProgress) {
currentProgress = maxProgress;
if (listener != null) {
listener.loadEnd();
}
}
this.currentProgress = currentProgress;
if (listener != null) {
listener.progressLoading(currentProgress);
}
invalidate();//重绘
}
public void setListener(ProgressedListener listener) {
this.listener = listener;
}
public interface ProgressedListener {
void loadEnd();//加载结束
void progressLoading(int progressed);//加载中
void startLoad();//开始加载
}
}
- 自定义属性 attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressView">
<!-- 背景色-->
<attr name="circleprogress_backgroundcolor" format="color" />
<!-- 前景色-->
<attr name="circleprogress_foregroundcolor" format="color" />
<!-- 进度条颜色 -->
<attr name="circleprogress_progresscolor" format="color" />
<!-- 字体颜色-->
<attr name="circleprogress_fontcolor" format="color" />
<!-- 最大进度 -->
<attr name="circleprogress_maxprogress" format="integer" />
<!-- 进度宽 -->
<attr name="circleprogress_width" format="integer" />
<!-- 字体大小-->
<attr name="circleprogress_textsize" format="integer" />
</declare-styleable>
</resources>
- 布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:circleprogress="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:background="#ffffff"
android:orientation="vertical"
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="com.wxq.me.mycsdndemo.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.wxq.me.mycsdndemo.CircleProgressView
android:id="@+id/circle_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
circleprogress:circleprogress_backgroundcolor="#dddddd"
circleprogress:circleprogress_fontcolor="#0000ff"
circleprogress:circleprogress_foregroundcolor="#ffffff"
circleprogress:circleprogress_maxprogress="100"
circleprogress:circleprogress_progresscolor="#0000ff" />
<com.wxq.me.mycsdndemo.CircleProgressView
android:id="@+id/circle_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
circleprogress:circleprogress_backgroundcolor="#000000"
circleprogress:circleprogress_fontcolor="#ff0000"
circleprogress:circleprogress_foregroundcolor="#ffffff"
circleprogress:circleprogress_maxprogress="100"
circleprogress:circleprogress_progresscolor="#ff0000"
circleprogress:circleprogress_textsize="20"
circleprogress:circleprogress_width="5" />
<com.wxq.me.mycsdndemo.CircleProgressView
android:id="@+id/circle_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
circleprogress:circleprogress_backgroundcolor="#ff0000"
circleprogress:circleprogress_fontcolor="#ffff00"
circleprogress:circleprogress_foregroundcolor="#ffffff"
circleprogress:circleprogress_maxprogress="100"
circleprogress:circleprogress_progresscolor="#ffff00"
circleprogress:circleprogress_textsize="20"
circleprogress:circleprogress_width="5" />
</LinearLayout>
<com.wxq.me.mycsdndemo.CircleProgressView
android:id="@+id/circle_view3"
android:layout_width="match_parent"
android:layout_height="match_parent"
circleprogress:circleprogress_backgroundcolor="#dddddd"
circleprogress:circleprogress_fontcolor="#00ffff"
circleprogress:circleprogress_foregroundcolor="#ffffff"
circleprogress:circleprogress_maxprogress="100"
circleprogress:circleprogress_progresscolor="#00ffff"
circleprogress:circleprogress_textsize="50"
circleprogress:circleprogress_width="20" />
</LinearLayout>
- MainActivity.java
public class MainActivity extends AppCompatActivity {
private CircleProgressView mCircleProgressView, mCircleProgressView1, mCircleProgressView2, mCircleProgressView3;
private int currentProgress = 0;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (currentProgress <= 100) {
mCircleProgressView.setCurrentProgress(currentProgress);
mCircleProgressView1.setCurrentProgress(currentProgress);
mCircleProgressView2.setCurrentProgress(currentProgress);
mCircleProgressView3.setCurrentProgress(currentProgress);
Log.i("wx", currentProgress + "");
currentProgress++;
sendEmptyMessageDelayed(1, 10);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCircleProgressView = (CircleProgressView) findViewById(R.id.circle_view);
mCircleProgressView1 = (CircleProgressView) findViewById(R.id.circle_view1);
mCircleProgressView2 = (CircleProgressView) findViewById(R.id.circle_view2);
mCircleProgressView3 = (CircleProgressView) findViewById(R.id.circle_view3);
mCircleProgressView.setListener(new CircleProgressView.ProgressedListener() {
@Override
public void loadEnd() {
Toast.makeText(MainActivity.this, "加载结束", Toast.LENGTH_SHORT).show();
}
@Override
public void progressLoading(int progressed) {
//TODO
}
@Override
public void startLoad() {
Toast.makeText(MainActivity.this, "加载开始", Toast.LENGTH_SHORT).show();
}
});
mHandler.sendEmptyMessageDelayed(1, 1000);
}
}
-
实现思路
- 在onDraw方法中先中绘制外圆,再去绘制扇形,再绘制内圆,最后绘制文字。
- 在CircleProgressView定义接口ProgressedListener,MainActivity中实现这个接口,开始加载回调startLoad方法,加载中回调progressLoading方法,加载结束回调loadEnd方法。
- 在MainActivity使用handler模拟进度加载调用setCurrentProgress方法。
-
下载地址
http://download.csdn.net/detail/zhe_ge_sha_shou/9650195