更新效果
因为view为圆型,我们需要在onMeasure中设置它长等于宽
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width>height?height:width, width>height?height:width);
}
思路:先绘制一圈灰色的圆环,蓝色圆弧动态覆盖
首先是灰色圆环
//初始灰色底圈
//创建一个Path
Path originPath = new Path();
RectF originRect = new RectF(0,0,getWidth(),getHeight());
//圆环起点在第一象限与第四象限交界处,顺时针旋转270°后才是12点方向
originPath.addArc(originRect,270,360);
//虚线
Path originRectPath = new Path();
//设置虚线的长宽和排列方式
originRectPath.addRect(0,0,4,24,Path.Direction.CCW);
PathEffect originPathEffect = new PathDashPathEffect(originRectPath, 14,8, PathDashPathEffect.Style.ROTATE);
//填充虚线
mOriginPaint.setPathEffect(originPathEffect);
canvas.drawPath(originPath,mOriginPaint);
用同样方式绘制蓝色圆弧,通过动态修改progress实现蓝色圆弧变化
Path changePath = new Path();
RectF changeRect = new RectF(0,0,getWidth(),getHeight());
changePath.addArc(changeRect,270,progress*360);
Path changeRectPath = new Path();
changeRectPath.addRect(0,0,4,mBorderWidth,Path.Direction.CCW);
PathEffect changePathEffect = new PathDashPathEffect(changeRectPath, 14,8, PathDashPathEffect.Style.ROTATE);
mChangePaint.setPathEffect(changePathEffect);
canvas.drawPath(changePath,mChangePaint);
在java代码中调用setProgress就可以控制蓝色圆环,如顶部图片效果
public void setProgress(float progress){
this.progress = progress;
invalidate();
}
检查更新
完成更新效果后,再来看下检查更新的动画(图片为压缩采样后得效果,看着不太顺滑)
check.gif
思路依然是蓝色覆盖灰色
灰色圆环复用之前代码... 省略
蓝色圆弧,这里把圆弧设置为60度,通过修改startAngle起始角度实现动态效果
Path changePath = new Path();
//检查更新
RectF updateRect = new RectF(0,0,getWidth(),getHeight());
// 圆弧起始角度,扫过角度
changePath.addArc(updateRect,startAngle,60);
Path updateRectPath = new Path();
updateRectPath.addRect(0,0,4,mBorderWidth,Path.Direction.CCW);
PathEffect changePathEffect = new PathDashPathEffect(updateRectPath, 14,8, PathDashPathEffect.Style.ROTATE);
mChangePaint.setPathEffect(changePathEffect);
canvas.drawPath(changePath,mChangePaint);
设置动画属性,同之前提过的初始角度在第一象限,第四象限交界处,这里的起始截至位置非0度-360度,而是270-630
private void initCheckAnimator(){
checkAnimator = ValueAnimator.ofFloat(270, 630);
checkAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
startAngle = ((Float) animation.getAnimatedValue());
invalidate();
}
});
checkAnimator.setInterpolator(null);//去掉默认插值器
checkAnimator.setDuration(1000); //1s循环一次
checkAnimator.setRepeatCount(-1);//无限重复
checkAnimator.start();
}
在java代码中调用check()和stopCheck()开始和停止动画
public synchronized void check(){
initCheckAnimator();
invalidate();
}
public void stopCheck(){
if (checkAnimator!=null&&checkAnimator.isStarted()){
checkAnimator.end();
}
}
网友评论