【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

今天给大家带来的是一个等待的动画效果↓

看到我的照片有没有被迷到啊随后我只能感叹一下岁月了

好,OK,下面我们来分析一下这个效果,收下我们可以看出这个动画是由三个动画组成,

1:6个小圆点的旋转.

2:一个弹一下的效果

3:一个水波纹扩散的效果

好的,下面我们就一个一个的来说一下。

首先我们说一下这个6个小球的旋转,我们都可以看出,这个六个小球也是在画一个大圆,所以我们只要把大圆的半径确定了之后,在计算每个小圆的角度,再不断的进行绘制是不是就可以了?对,没错,就是这样的。那么在这之前我们是不是应该找到中间大圆的中心点,并且计算出半径啊。

其实这个中心点就是屏幕对角线的一半,请看代码

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

通过在onSizeChanged方法中的计算之后,我们就可以确定了中间空心圆的中心点了,那么我们还要确定的就是这个每个小圆每次的角度,所以我们需要在绘制之前进行起算。因为会不止一次使用,所以我就直接写了一个方法,大家请看!

上面我已经把注释写的很清楚了,不懂的也可以留言再问,我会给大家解释的。

看完上面的代码,之后,你肯定在想,如果一直绘制小圆,最后小圆是不是就不止6个啊 ,是不是每绘制一次就+6个小圆啊,没错,所以我们在绘制之前还需要把之前的擦掉,怎么擦呢?很简单,调用canvas.drawColor(mSplashBgColor);把整个画布画成白色不就完事了。

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

那么我们应该怎么启动呢?又到了这次的亮点了。再分析下啊,刚才我们也说了,这个动画效果是由三个效果组成的,也可以说是动画分为三个状态,那么可不可用一个变量引用不同的对象来达到不同的效果呢?答案是肯定的,这就是策略模式!所以我在这里写了一个抽象类。

private abstract class SplashState {public abstract void drawState(Canvas canvas);
}
//这里利用一个设计模式:策略模式
private SplashState mstate = null;

用三个不同的类去继承他,实现抽象方法。第一个状态就是小球旋转。

在一上来的时候我们就应该来让小球转起来,所以我们在OnDraw方法就要实例化第一个对象。

@Override
protected void onDraw(Canvas canvas) {//绘制动画第一个动画
    if (mstate == null) {mstate = new RotationState();}mstate.drawState(canvas);super.onDraw(canvas);
}

因为我们需要让他不断的刷新并且还要计算每个小圆的角度,所以我们对动画进行监听。

/**
 * 第一个动画:小圆旋转动画
 * 要素:不断的绘制小圆--》控制左边---- 旋转的角度、公转的半径
 */
private class RotationState extends SplashState {public RotationState() {//动画初始化
        //1600ms,计算某个时间当前的角度是多少:0~2π中的某个值
        valueAnimator = ValueAnimator.ofFloat(0, (float) Math.PI * 2);valueAnimator.setInterpolator(new LinearInterpolator());//设置插值器,主要是为了小圆点的旋转时间平均,让动画没有停顿。
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//回调监听
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {//得到某个时间点计算的结果 ----这个时间带你当前大圆旋转的角度
                mCurrentRotationAngle = (float) animation.getAnimatedValue();postInvalidate();}});valueAnimator.setDuration(mRotationDuration);//动画时间
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);//不断重复
        valueAnimator.start();//启动
    }public void cancle() {valueAnimator.cancel();}@Override
    public void drawState(Canvas canvas) {//绘制动画
        //1擦黑板
        drawBackground(canvas);//2.画小圆
        drawCircle(canvas);}
}

在这里可以看出,这个动画是不间断的,所以在我们的耗时操作完毕后,我们应该让它进入下一个状态,也就放大之后再缩小,那么我们就应该实例化下一个对象了。首先我们应该写一个公有方法,让我们可以在外面调用

/**
 * 这个方法是加载完数据之后调用的方法
 * 主要意思就是加载完数据之后需要更换动画了
 */
public void splashDisappear() {//完毕后开启进场的动画------1.个动画结束、2.3.动画开启
    if (mstate != null && mstate instanceof RotationState) {RotationState rotationstate = (RotationState) mstate;rotationstate.cancle();//停止当前的动画
        post(new Runnable() {@Override
            public void run() {mstate = new MergingState();//开启第二个动画
            }});}
}

【独具匠心 http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

那么第二个状态到底干了什么呢?其实就是把当前圆的半径一直缩小到0。那为什么会有放大的效果呢?因为用了一个插值器来操作的。所以说第二个状态就是在把当前的圆的半径缩小到0之前放大了一下,并且对动画进行了监听了,不断的进行绘制。

/**
 * 第二个动画  聚合动画
 */
private class MergingState extends SplashState {public MergingState() {//动画初始化
        //1600ms,计算某个时间当前的公转的半径是多少:r~0中的某个值
        valueAnimator = ValueAnimator.ofFloat(0, mRotationRadius);valueAnimator.setInterpolator(new OvershootInterpolator(10f));//谈一下的效果  也就是放大了一下
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//回调监听
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {//得到某个时间点计算的结果 ----这个时间点当前大圆旋转的半径
                mCurrentRotationRadius = (float) animation.getAnimatedValue();postInvalidate();}});//动画结束后实例化第三个动画
        valueAnimator.addListener(new AnimatorListenerAdapter() {@Override
            public void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);mstate = new ExpandState();}});valueAnimator.setDuration(mRotationDuration);//动画持续时间
        valueAnimator.reverse();//反转执行
    }@Override
    public void drawState(Canvas canvas) {//这个方法是把背景全部画成白色
        drawBackground(canvas);//画六个小圆
        drawCircle(canvas);}
}   

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

从上面的代码可以看出,在动画结束后,改变了对象的引用,本来我想的是直接给大家贴上代码就拉到了,但是想到当时我再写这个地方的时候也很懵所以先给大家说一说这里吧!

首先说这个扩散的效果并不是很动画效果,也是自己绘制的。怎么绘制的呢?画圆!

先不要看里面,先看外面这个大圆,就是一直从内到外的画出来的,也就是说我们一直在上面一层操作,当网络加载完之后把下面一层呈现出来就好了!

下面说下是怎么画的,首先我们要准备一只很粗的笔,也就是这个大圆半径粗的笔,然后不断的让笔越来越细就好了。这里还有个点,就是怎么确定每次的落笔的地方。因为需要落笔点,这个相信大家都知道,我就不多说了。上面的图,虽然不是很好看,但是我感觉意思应该明白了。OK!那就看一下最一个对象吧!

/**
 * 第三个动画:水波纹空心扩散动画
 */
private class ExpandState extends SplashState {public ExpandState() {//1600ms,计算某个时间当前的空心圆的半径是多少:0~~~~对角线/2中的某个值
        valueAnimator = ValueAnimator.ofFloat(0, mDiagonaalDist);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//回调监听
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {//得到某个时间点计算的结果 ----这个时间点当前空心圆的半径
                mHoleRadius = (float) animation.getAnimatedValue();postInvalidate();}});valueAnimator.setDuration(mRotationDuration);//动画持续时间
        valueAnimator.start();//启动
    }@Override
    public void drawState(Canvas canvas) {//这里只需要重新绘制空心圆就好了  不用画小圆了
        drawBackground(canvas);}
}

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】

最后呢!想跟大家说的是,文章看不到最后,这个效果是出不来的,所以我把完整代码放在这里!嘿嘿,有什么疑问可以留言哟,我会及时回复的

Android 自绘动画效果---小清新等待相关推荐

  1. Android 卡片翻转动画效果

    转载请标明出处:http://blog.csdn.net/android_mnbvcxz/article/details/78570594 Android 卡片翻转动画效果 前言 前端时间开发一款应用 ...

  2. Android中具有动画效果的图片资源

    Android动画和Transition系列文章 初识属性动画--使用Animator创建动画 再谈属性动画--介绍以及自定义Interpolator插值器 三谈属性动画--Keyframe以及Vie ...

  3. 【Android笔记25】Android中的动画效果之逐帧动画

    这篇文章,主要介绍Android中的动画效果之逐帧动画. 目录 一.逐帧动画 1.1.什么是逐帧动画 1.2.逐帧动画的使用 (1)创建drawable动画资源<

  4. Android颜色渐变动画效果的实现

    系列文章目录 Android颜色渐变动画效果的实现 文章最后有源码 文章目录 系列文章目录 前言 一.Android中插值器TypeEvaluator. 二.案例效果实现 1.利用Android自带的 ...

  5. Android 雪花飘落动画效果 自定义View

    在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...

  6. android 自定义view 动画效果,Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又 ...

  7. android 翻书动画效果怎么做,android ViewPager实现滑动翻页效果实例代码

    实现ViewPager的滑动翻页效果可以使用ViewPager的setPageTransformer方法,如下: import android.content.Context; import andr ...

  8. Android 展开/收回动画效果思路与实现

    要实现什么效果? 我们就是要实现如图所示的动画效果,在开始之前我们先了解一下实现这个动画的相关知识. 属性动画相关知识 动画执行的逻辑 逻辑大概流程如下: 为 ValueAnimator 设置动画的时 ...

  9. android 播放gif动画效果,android 通过帧动画方式播放Gif动画

    注意:经过本人测试,这个方法很耗内存, 图片一多就崩了.慎用 <1>用工具(photoshop或者FireWorks)将GIF动画图片分解成多个GIF静态图片,然后保存在res\drawa ...

最新文章

  1. 一晚上就能让你小腹变小的方法 - 健康程序员,至尚生活!
  2. 详解zabbix安装部署(Server端篇)
  3. Oracle PL/SQL编程之包(packages)
  4. python 自然语言处理(三)获取词性
  5. 通过 Go 语言来实现 DDD 分层设计,美滋滋!
  6. Scrum之 Sprint计划会议
  7. hive-内置函数(常用内置函数汇总)
  8. 程序员必备的10大健康装备!
  9. oracle学习总结1
  10. 全国计算机等级考试在线报名,全国计算机等级考试网上报考具体流程
  11. Android小程序白屏,微信小程序web-view跳转h5 安卓白屏
  12. 我国计算机辅助翻译专业,我国翻译硕士专业之计算机辅助翻译课程调查.pdf
  13. 【Kubernetes 系列】一文学会Kubernetes Service安全的暴露应用
  14. 根据身份证获取用户的年龄,性别,生日等
  15. 浅析中西思维差异对英语口语交际的影响
  16. 兑换记录html页面,兑换码记录.html
  17. bcn_timout,ap_probe_send_start
  18. C# System.Net.Mail 类 使用465端口邮件不成功
  19. QSystemTrayIcon退出后系统托盘图标不消失问题
  20. nosql包括的数据库

热门文章

  1. 首届中国IT架构大师高峰论坛
  2. 您的计算机和打印机上的打印设置不匹配,解决打印机怪异提示之打印端口不匹配...
  3. 自制拖把机器人_连拖布都能自己清洗 智能扫拖机器人再添新技能
  4. 小米IoT安全峰会—Markus Hinkelmann《Beyond logical attacks》
  5. MongoDB 复制(副本集)学习
  6. PYTHON代码审查工具
  7. 计算机网络与python知识点总结
  8. php 下载s3文件系统,如何使用php和Amazon S3 sdk下载文件?
  9. android系统流畅度排行,这个手机操作系统流畅度排行,你认可吗?
  10. 星号实现的三角形(C语言)