1.1、添加在vules中的Color中
<declare-styleable name="ProgressView">
<!--circleColor 设置圆形边框的颜色 sweepColor设置扇形变换的颜色
startAngle 设置起始角度 sweepStep 设置变换的步长-->
<attr name="circleColor" format="color|reference"></attr>
<attr name="sweepColor" format="color|reference"></attr>
<attr name="startAngle" format="integer"></attr>
<attr name="sweepStep" format="integer"></attr>
<attr name="padding" format="integer"></attr>
</declare-styleable>
1.2、布局
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onPlay"
android:text="点击自定义View"/>
<com.baway.www.circleviewdemo.ProgressView
android:layout_width="260dp"
android:layout_height="260dp"
android:id="@+id/onPro"/>
1、代码实现
public class ProgressView extends View {
private int sweepStep = 10;//扇形变换的步长(就是角度)
private int padding = 15;//外边框距离扇形的距离 填充
private int circleColor = Color.YELLOW;//边框的颜色
private int sweepColor = Color.GREEN;//扇形颜色
private int startAngle = 90;//起始角度
//设置外边框圆的边框粗细
private int storke = 20;
private int sweepAngle = 0;//扫过的角度
private static final int DEFAULT_WIDTH = 200;
private static final int DEFAULT_HEIGHT = 200;
public ProgressView(Context context) {
super(context);
}
//如果要在xml文件中使用该自定义控件,则必须重写两个参数的构造函数
//因为我们使用自定义的属性的时候,会默认传递过来一个AttributeSet集合
public ProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);
if (array != null) {
//获取我们在xml中设置的各个自定义属性
sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep, sweepStep);
padding = array.getInteger(R.styleable.ProgressView_padding, padding);
circleColor = array.getColor(R.styleable.ProgressView_circleColor, circleColor);
sweepColor = array.getColor(R.styleable.ProgressView_sweepColor, sweepColor);
startAngle = array.getInteger(R.styleable.ProgressView_startAngle, startAngle);
//回收TypeArray资源
array.recycle();
}
}
//先绘制外边框 --内部扇形
int one = 360;
int two = 360;
int three = 360;
int fore =360;
@Override
protected void onDraw(Canvas canvas) {
Paint mPaint = new Paint();
mPaint.setAntiAlias(true); //设置抗锯齿
//绘制外层的圆框
mPaint.setColor(circleColor);
mPaint.setStrokeWidth(storke);
mPaint.setStyle(Paint.Style.STROKE);//设置圆形为空心的圆
//这里我们得到控件的Height和Width,根据Heigh和Width来确定圆心的位置,来绘制外层圆
canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - storke / 2, mPaint);
// Log.d("tag", "onDraw: "+getWidth());
invalidate();//请求重新绘制view
//绘制内部的扇形
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(sweepColor);
RectF rectF1 = new RectF(one,two,three,fore);
canvas.drawArc(rectF1, 360f, 360f, true, mPaint);
one = one -2;
two = two - 2;
three=three+2;
fore=fore+2;
one = one<(padding + storke)?(padding + storke):one;
two = two<(padding + storke)?(padding + storke):two;
three = three>(getWidth() - padding - storke)?(getWidth() - padding - storke):three;
fore = fore>(getWidth() - padding - storke)?(getWidth() - padding - storke):fore;
invalidate();//重绘view
}
//因为我们是继承的View来自定义的View,所以onMeasure()方法要重写
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
int wSize = MeasureSpec.getSize(widthMeasureSpec);
int hSize = MeasureSpec.getSize(heightMeasureSpec);
//因为绘制的是圆,所以判断一下高度或者宽度中的一个就可以。
switch (wMode) {
case MeasureSpec.AT_MOST://android:layout_width="warp_content"
//获取屏幕像素
float density = getResources().getDisplayMetrics().density;
wSize = (int) (DEFAULT_WIDTH * density);
hSize = (int) (DEFAULT_HEIGHT * density);
break;
//当在xml中指定控件的宽高为match_parent或者指定数值的宽高时,回调以下代码
case MeasureSpec.EXACTLY://android:layout_width="match_parent" android:layout_width="40dp"
wSize = hSize = Math.min(wSize, hSize);
break;
}
//只要重写onMeasure()方法,一定要调用以下方法,不然会报错
setMeasuredDimension(wSize, hSize);
}
public void onInfo(){
postInvalidate();
one = 360;
two = 360;
three = 360;
fore =360;
};
}
2、MainAcitity主方法
public class MainActivity extends AppCompatActivity {
private ProgressView onPro;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onPro = (ProgressView) findViewById(R.id.onPro);
}
public void onPlay(View v){
new Thread(){
@Override
public void run() {
super.run();
onPro.onInfo();
}
}.start();
}
}