自定义View实现圆形围绕加载动画
自定义属性
<declare-styleable name="custom_loading_view">
<attr name="center_text" format="string" />
<attr name="center_text_color" format="color"/>
<attr name="center_text_size" format="dimension"/>
<attr name="inside_cycle_width" format="dimension"/>
<attr name="inside_cycle_color" format="color"/>
<attr name="outside_cycle_width" format="dimension"/>
<attr name="outside_cycle_color" format="color"/>
<attr name="loading_point_width" format="dimension"/>
<attr name="loading_point_color" format="color"/>
</declare-styleable>
自定义类继承view
public class CustomLoadingView extends View {
int insideCycleWidth;
int insideCycleColor;
int outsideCycleWidth;
int outsideCycleColor;
int loadingPointWidth;
int loadingPointColor;
int centerTextSize;
int centerTextColor;
String centerText;
private float scale;
public int getCenterTextSize() {
return centerTextSize;
}
public void setCenterTextSize(int centerTextSize) {
this.centerTextSize = centerTextSize;
}
public String getCenterText() {
return centerText;
}
public void setCenterText(String centerText) {
this.centerText = centerText;
invalidate();
}
public CustomLoadingView(Context context) {
this(context,null);
}
public CustomLoadingView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CustomLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
scale = context.getResources().getDisplayMetrics().density;
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.custom_loading_view,defStyleAttr,0);
centerTextSize = a.getDimensionPixelSize(R.styleable.custom_loading_view_center_text_size,25);
centerTextColor = a.getColor(R.styleable.custom_loading_view_center_text_color,getResources().getColor(R.color.colorPrimary));
insideCycleWidth = a.getDimensionPixelSize(R.styleable.custom_loading_view_inside_cycle_width,90);
insideCycleColor = a.getColor(R.styleable.custom_loading_view_inside_cycle_color,getResources().getColor(R.color.colorAccent));
outsideCycleWidth = a.getDimensionPixelSize(R.styleable.custom_loading_view_outside_cycle_width,9);
outsideCycleColor = a.getColor(R.styleable.custom_loading_view_outside_cycle_color,getResources().getColor(R.color.colorAccent));
loadingPointWidth = a.getDimensionPixelSize(R.styleable.custom_loading_view_loading_point_width,10);
loadingPointColor = a.getColor(R.styleable.custom_loading_view_loading_point_color,getResources().getColor(R.color.colorAccent));
centerText = a.getString(R.styleable.custom_loading_view_center_text);
Log.e("==========","=======文字====="+centerText);
a.recycle();
}
private Paint paint;
private int progress;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint = new Paint();
//画最外层圈设置成空心
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(outsideCycleColor);
paint.setStrokeWidth(outsideCycleWidth);
paint.setStyle(Paint.Style.STROKE);
int outR = width/2 - outsideCycleWidth*2;
canvas.drawCircle(width/2,height/2,outR,paint);
//计算中心点半径和左边,画内部实心圆
int innerR = outR - insideCycleWidth;
paint.setStrokeWidth(innerR);
paint.setColor(insideCycleColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(width/2,height/2,innerR,paint);
//画中心的Text,计算text的宽高,设置text的开始位置或者中心点,计算baseline(y)的位置
paint.setTextSize(centerTextSize*scale+0.5f);
paint.setColor(centerTextColor);
float v = paint.measureText(centerText);
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(centerText,width/2,height/2+textHeight/4,paint);
//画最外层移动的圆点
paint.setStrokeWidth(loadingPointWidth*scale+0.5f);
paint.setColor(loadingPointColor);
//此方法的画扇形加载形式
// RectF rect = new RectF(loadingPointWidth,loadingPointWidth,width-loadingPointWidth,height-loadingPointWidth);
// paint.setStyle(Paint.Style.STROKE);
// canvas.drawArc(rect,0,progress,false,paint);
canvas.drawCircle((float) (width/2 + outR * Math.sin(progress* Math.PI / 180)),
(float) (height/2 - outR * Math.cos(progress* Math.PI / 180)),
loadingPointWidth/2, paint);
}
private int width,height;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(Math.min(width, height), Math.min(width, height));
}
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
//用来执行加载动画
@SuppressLint("HandlerLeak")
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
progress+=4;
if (progress == 360){
progress = 0;
}
setProgress(progress);
}
};
private boolean startAnim;
Thread t;
public void startLoadingAnim(){
startAnim = true;
t = new Thread(new Runnable() {
@Override
public void run() {
while (startAnim) {
try {
Thread.sleep(20);
handler.sendEmptyMessage(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
public void stopLoadingAnim(){
startAnim = false;
t.interrupt();
}
}