您的位置:首页 > 移动开发 > Android开发

Android高效率实现win8进度条效果,手把手教会你实现效果,项目中直接使用

2017-01-13 23:49 756 查看
转载请注明出处:http://blog.csdn.net/jakeyangchina/article/details/54413523

新的一年新的开始,2017年争取每个星期至少一篇技术博客,方便日后复习,今天实现win8进度条效果,好多app页面都能看到这样的效果,利用休息时间我也来实现此效果,分享给大家,共同进步。

录制效果不是很好,不过运行在手机上效果还是好的

按照惯例先展示效果图:



功能介绍:

开启页面时,有五个小圆球开始从左向右运动,先减速运动,再加速运动

思路分析:

绘制五个实心圆

给圆添加动画效果

依次给五个小球设置开启延时时间,延时时间倍速增长

自定义插值器,实现减速加速运动

开启动画,时刻更新位置绘制圆

这里需要注意:

这里使用属性动画:ObjectAnimator.ofFloat(this,”fourCircleRadius”,startPosition, endPosition);

参数一:指定给哪个对象添加动画效果

参数二:属性名(方法名)

参数三:开始的位置

参数四:结束的位置

这里要注意的是参数的值,查看系统源码得知,内部是通过反射获取到方法,getXX和setXX方法,参数三和参数四就是传给setXX方法,指定起始位和结束位置,系统内部自动按照插值器返回的值进行计算把值传给setXX方法,仿照系统源码在本类中定义setXX方法,在此方法中调用invalidate()方法,位置改变时刻更新绘制

还需要注意一个地方:小球运动的起始位置和结束位置,指定起始位和结束位置要超出屏幕,要不然运动起来很不美观

接下来展示重要代码,代码标注的很详细,可以下载源码

字段


//布局文件的宽度
private int width;
//布局文件的高度
private int height;
//动画开始的位置,在屏幕之外
private float startPosition = -20;
//动画结束的位置,在屏幕之外,动态赋值
private float endPosition;
//给圆的位置初始化值,先从屏幕之外开始运动
private float oneValue = startPosition;
private float twoValue = startPosition;
private float threeValue = startPosition;
private float fourValue = startPosition;
private float fiveValue = startPosition;
//动画的延时时间
private long delaye = 90;
//动画运动的时间
private int duration = 1500;
//用于判断是否关闭页面,关闭动画
private boolean isFinish = false;
//首次运行,只允许运行一次
private boolean isFirst = false;
//创建第一个圆的画笔
private Paint paintOneCircle;
//创建第二个圆的画笔
private Paint paintTwoCircle;
//创建第三个圆的画笔
private Paint paintThreeCircle;
//创建第四个圆的画笔
private Paint paintFourCircle;
//创建第五个圆的画笔
private Paint paintFiveCircle;
//第一个圆的动画对象
private ObjectAnimator oneCircleAnimator;
//第二个圆的动画对象
private ObjectAnimator twoCircleAnimator;
//第三个圆的动画对象
private ObjectAnimator threeCircleAnimator;
//第四个圆的动画对象
private ObjectAnimator fourCircleAnimator;
//第五个圆的动画对象
private ObjectAnimator fiveCircleAnimator;


这里定义了五个圆,五个画笔,也可以定义一个画笔,在这里略

init()


    /**
* 初始化
*/
private void init(){
//创建第一个圆的画笔
paintOneCircle = new Paint();
paintOneCircle.setAntiAlias(true);
paintOneCircle.setColor(Color.BLUE);

//创建第二个圆的画笔
paintTwoCircle = new Paint();
paintTwoCircle.setAntiAlias(true);
paintTwoCircle.setColor(Color.BLUE);

//创建第三个圆的画笔
paintThreeCircle = new Paint();
paintThreeCircle.setAntiAlias(true);
paintThreeCircle.setColor(Color.BLUE);

//创建第四个圆的画笔
paintFourCircle = new Paint();
paintFourCircle.setAntiAlias(true);
paintFourCircle.setColor(Color.BLUE);

//创建第五个圆的画笔
paintFiveCircle = new Paint();
paintFiveCircle.setAntiAlias(true);
paintFiveCircle.setColor(Color.BLUE);

}


这个方法是初始化画笔

onSizeChanged()方法


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(!isFirst) {
//执行一次
isFirst = true;
//获取布局宽度
width = getWidth();
//获取布局高度
height = getHeight();
//设置动画结束的位置,一定要在屏幕外结束
endPosition = 20 + width;
//初始化动画
initAnima();
//开启动画
startAnima();
}
}


onSizeChanged这个方法当布局尺寸改变时会回调,在这里获取控件宽高,这里需要注意endPosition值,指结束位置要超出屏幕,要不然小球运动结束后效果不美观

initAnima()


    /**
* 初始化动画
*/
private void initAnima(){
//创建第一个动画
oneCircleAnimator = ObjectAnimator.ofFloat(this, "oneCircleRadius", startPosition, endPosition);
oneCircleAnimator.setDuration(duration);
oneCircleAnimator.setStartDelay(delaye);
oneCircleAnimator.setInterpolator(new MyTimeInterpolator());

//创建第二个动画
twoCircleAnimator = ObjectAnimator.ofFloat(this, "twoCircleRadius", startPosition, endPosition);
twoCircleAnimator.setDuration(duration);
twoCircleAnimator.setStartDelay(delaye*2);
twoCircleAnimator.setInterpolator(new MyTimeInterpolator());

//创建第三个动画
threeCircleAnimator = ObjectAnimator.ofFloat(this, "threeCircleRadius", startPosition, endPosition);
threeCircleAnimator.setDuration(duration);
threeCircleAnimator.setStartDelay(delaye*3);
threeCircleAnimator.setInterpolator(new MyTimeInterpolator());

//创建第四个动画
fourCircleAnimator = ObjectAnimator.ofFloat(this, "fourCircleRadius", startPosition, endPosition);
fourCircleAnimator.setDuration(duration);
fourCircleAnimator.setStartDelay(delaye*4);
fourCircleAnimator.setInterpolator(new MyTimeInterpolator());

//创建第五个动画
fiveCircleAnimator = ObjectAnimator.ofFloat(this, "fiveCircleRadius", startPosition, endPosition);
fiveCircleAnimator.setDuration(duration);
fiveCircleAnimator.setStartDelay(delaye*5);
fiveCircleAnimator.setInterpolator(new MyTimeInterpolator());
fiveCircleAnimator.addListener(this);
}


上面方法是初始化动画,这里需要注意设置每个小球的延时时间,为了让小球逐个运动,这样效果美观

startAnima()


    /**
* 开启动画
*/
private void startAnima(){
//isFinish用于判断是否退出,当退出时不允许在开启动画
if(!isFinish) {
oneCircleAnimator.start();
twoCircleAnimator.start();
threeCircleAnimator.start();
fourCircleAnimator.start();
fiveCircleAnimator.start();
}
}


这个刚发是开启动画

onDraw()


@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画第一个圆
canvas.drawCircle(oneValue,height/2,10,paintOneCircle);

//画第二个圆
canvas.drawCircle(twoValue,height/2,10,paintTwoCircle);

//画第三个圆
canvas.drawCircle(threeValue,height/2,10,paintThreeCircle);

//画第四个圆
canvas.drawCircle(fourValue,height/2,10,paintFourCircle);

//画第五个圆
canvas.drawCircle(fiveValue,height/2,10,paintFiveCircle);

}


在这个方法中绘制五个小圆

/**
* 更新第一个圆的位置
* @param value
*/
private void setOneCircleRadius(float value) {
this.oneValue = value;
//更新绘制
invalidate();
}

/**
* 更新第二个圆的位置
* @param value
*/
private void setTwoCircleRadius(float value) {
this.twoValue = value;
//更新绘制
invalidate();
}

/**
* 更新第三个圆的位置
* @param value
*/
private void setThreeCircleRadius(float value) {
this.threeValue = value;
//更新绘制
invalidate();
}

/**
* 更新第四个圆的位置
* @param value
*/
private void setFourCircleRadius(float value) {
this.fourValue = value;
//更新绘制
invalidate();
}

/**
* 更新第五个圆的位置
* @param value
*/
private void setFiveCircleRadius(float value) {
this.fiveValue = value;
//更新绘制
invalidate();
}


上方这五个方法很重要,当开启动画时,ObjectAnimator.ofFloat(this,”fourCircleRadius”,startPosition, endPosition);五个动画就会调用对应的方法,通过第二个参数指定方法名,内部通过反射获取,要时刻调用invalidate();更新绘制位置

onAnimationEnd()这个方法是动画监听器中的方法


@Override
public void onAnimationEnd(Animator animation) {
//当最后一个动画结束后,从新开启所有动画
startAnima();
}


上面方法是给最后 一个动画添加监听器,当最后一个动画运动结束时,从新开启运动,这里也可以使用另一种方法,就是给动画设置循环播放(大家可以试验)

/**
* 自定义插值器,实现小球减速加速运动效果
*/
private class MyTimeInterpolator implements TimeInterpolator {

@Override
public float getInterpolation(float input) {
//先减速,再加速
return (float) (Math.asin(2 * input - 1) / Math.PI + 0.5);
}
}


这个方法是自定义插值器,实现小球运动的效果

这里MainActivity方法就不给列出了,详细下载Demo,代码里标注很详细

如果你觉得此文章对你有收获,那么就顶下,你的无意间的动作就是我写出好文章的动力,希望能够帮助到大家,共同进步

如果大家还有什么疑问,请在下方留言。

源码下载,请点击这里!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐