昨天我们已经做了一个仿搜狗浏览器的加载的动画,今天我们再接再厉做一个百度网页加载时的动画,大家可能会疑惑,我们天天用百度,没见什么动画啊,哥们,只能说明你的网速比较好,确实,我为了给大家录下这个动画,还专门把浏览器的速度限制在10kb/s的情况下给你截取的。切看效果图:
感觉是不是很不错,我也觉得不错,所以自己也试试怎么实现,我们先来分析下怎么实现。
1、中间的圆固定不动,两边的圆对称运动。
2、每次当两边的圆在中点相遇,则改变颜色。
技术点分析清楚,根据我们上篇博客的基础,这个效果实现还是比较简单的。基础知识点还是利用我们的属性动画进行绘制。所以属性动画大家还是去学习下,确实有很大用处。下面我们来以技术点为主线分析实现,最后给大家源码参考。
1、首先我们要设定我们动画的执行范围,即x坐标的范围,如下:
//浮动的边长
private int halfDistance = 60;
//中心点的x、y,当前点的x
private int centerX,centerY,currentX;
//最左边的起始点坐标x
private int startX;
...
centerX = getWidth()/2;
centerY = getHeight()/2;
startX = (int) (centerX - halfDistance * density);
2、其次,我们需要进行动画编写,同样是使用属性动画来控制x的变动:
/** * 执行动画 */
private void playAnimator(){
ValueAnimator valueAnimator = ValueAnimator.ofInt(startX,centerX - circleRadius/2);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentX = (int) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.setRepeatCount(-1);
valueAnimator.setDuration(400);
valueAnimator.setRepeatMode(2);
valueAnimator.start();
}
同样,为了效果,可以设置它的setInterpolator()加速效果,这样的效果一定很不错,我们暂时就不设置了。同时属性动画,我们只需要给出x的变化范围就好:startX < x < centerX - circleRadius/2,我们不让这三个圆有完全重叠,防止颜色叠加的效果差。
3、动画实现了,接下来就是实现绘制圆形了,这里,我们只需要控制下颜色的变换条件即可。
/** * 绘制圆形 * @param canvas */
private void drawCircle(Canvas canvas){
if(Math.abs(currentX - centerX) <= circleRadius/2){
colorIndex++;
mPaint.setColor(colors[colorIndex % 3]);
}else{
mPaint.setColor(colors[colorIndex]);
}
canvas.drawCircle(centerX, centerY, circleRadius, mPaint);
mPaint.setColor(colors[(colorIndex + 1) % 3]);
canvas.drawCircle(currentX, centerY, circleRadius, mPaint);
mPaint.setColor(colors[(colorIndex + 2) % 3]);
canvas.drawCircle(2 *centerX - currentX,centerY,circleRadius,mPaint);
if(colorIndex == 3)colorIndex=0;
}
我们通过colorIndex进行颜色值的选择,当它们x的差值小于circleRadius/2即进行变化。下面的两个圆就是利用对称效果进行绘制出来的,没什么复杂度,简单的逻辑。
看我们的效果图吧!
效果还是有那么点像的,欢迎大家提意见改进。以下就是源码:
/** * Created by dsw on 2015/10/11. */
public class BaiduLoading extends View {
//画笔
private Paint mPaint;
//圆形的半径
private int circleRadius = 20;
//浮动的边长
private int halfDistance = 60;
private float density;
//颜色的下标
private int colorIndex = 0;
//指定的颜色
private int colors[] = new int[]{Color.parseColor("#EE454A"),Color.parseColor("#2E9AF2"),
Color.parseColor("#616161")};
//中心点的x、y,当前点的x
private int centerX,centerY,currentX;
//最左边的起始点坐标x
private int startX;
public BaiduLoading(Context context, AttributeSet attrs) {
super(context, attrs);
density = getResources().getDisplayMetrics().density;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
centerX = getWidth()/2;
centerY = getHeight()/2;
startX = (int) (centerX - halfDistance * density);
if(currentX == 0){
playAnimator();
}else{
drawCircle(canvas);
}
}
/** * 执行动画 */
private void playAnimator(){
ValueAnimator valueAnimator = ValueAnimator.ofInt(startX,centerX - circleRadius/2);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentX = (int) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.setRepeatCount(-1);
valueAnimator.setDuration(400);
valueAnimator.setRepeatMode(2);
valueAnimator.start();
}
/** * 绘制圆形 * @param canvas */
private void drawCircle(Canvas canvas){
if(Math.abs(currentX - centerX) <= circleRadius/2){
colorIndex++;
mPaint.setColor(colors[colorIndex % 3]);
}else{
mPaint.setColor(colors[colorIndex]);
}
canvas.drawCircle(centerX, centerY, circleRadius, mPaint);
mPaint.setColor(colors[(colorIndex + 1) % 3]);
canvas.drawCircle(currentX, centerY, circleRadius, mPaint);
mPaint.setColor(colors[(colorIndex + 2) % 3]);
canvas.drawCircle(2 *centerX - currentX,centerY,circleRadius,mPaint);
if(colorIndex == 3)colorIndex=0;
}
}
大家对录制gif动画有比较好的软件推荐么?我用的都教授效果不是很好。大家有好的推荐一个吧!
资源下载地址
github下载地址
作者:mr_dsw 欢迎转载,与人分享是进步的源泉!
转载请保留地址:http://blog.csdn.net/mr_dsw