android刷新时的圆形动画_Android动画篇(一):圆形进度条CircleProgressBar

前言#

最近看框架和源码比较多,很久没有写动画了,相信很多的朋友都对动画感兴趣,我也不例外,毕竟做前端还是要靠动画特效吃饭的,并且比写功能模块更有成就感。

今天我们就来个稍微简单一点的CircleProgressBar热个身。

首先需要对ValueAnimator动画,还有Canvas,Paint画图的相关的类和API都有一定的了解,所以这部分还比较薄弱的朋友可以先去学习一下基础知识,否则可能会有些吃力。

正文#

先看一下效果图,我不会录屏,就百度了一张图片:

这里写图片描述

大概是这样的效果,首先我们不考虑效果,先画出这个圆形的进度条,新建文件CircleProgressBar:

/**

* 进度

*/

private float mProgress = 50;

/**

* 最大进度

*/

private int mMaxProgress = 100;

/**

* 绘制进度条

*/

private void drawProgress(Canvas canvas) {

// 开始画进度条

// 首先画出背景圆

mPaint.setColor(mBackgroundColor);

mPaint.setStyle(Paint.Style.FILL);

// 这里减去了边框的宽度

canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius - mBorderWidth, mPaint);

// 画出进度条

mPaint.setColor(mProgressBorderColor);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(mBorderWidth);

// 计算圆弧划过的角度

float angle = CIRCULAR / mMaxProgress * mProgress;

// 这里要画圆弧

canvas.drawArc(mContentRectF, -90, angle, false, mPaint);

// 画出补全部分的进度条

mPaint.setColor(mBorderColor);

mPaint.setStrokeWidth(mBorderWidth);

// 这里要画圆弧

canvas.drawArc(mContentRectF, -90 + angle, CIRCULAR - angle, false, mPaint);

}

先话出背景色的圆,然后画出进度条的颜色的边框,再画出进度条以外的部分,为了显示的明显,我分别用了三个颜色,最终的效果:

这里写图片描述

最初的样子已经出来了,但是有一个小细节要注意:

这里贴出mMaxProgress = 100,为什么不是1000,10000呢?当然也可以,但是我不推荐这个数字过大,大家可以去看看系统自带的ProgressBar,他的注释有提醒开发者,不要使用过大的max,最好是100,感兴趣的可以去看一看。

现在就差动画了,接下来我们来分析一下动画:

1、首先进度会飞快的上涨,以顺时针为方向,伸长的部分是头部。

2、然后进度会飞速的下降,以顺时针为方向,缩短的部分是尾部。

首先我们来完成第一部分:

/**

* 开始过度动画

*/

private void startIntermediateAnim() {

if (valueAnimator == null) {

valueAnimator = new ValueAnimator().ofFloat(0, mMaxProgress);

valueAnimator.setDuration(DURATION);

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator valueAnimator) {

// 设置进度

float value = (float) valueAnimator.getAnimatedValue();

setProgress(value);

}

});

valueAnimator.setRepeatCount(-1);

valueAnimator.start();

}

也是没什么太多的技术含量,但是有几点需要说明一下:

我们使用ValueAnimator().ofFloat,是为了动画的流畅性,如果你使用了int,你会发现动画会有一些细微的卡顿,因为int型舍弃了小数部分,这样就会出现误差,视觉上就会出现卡顿。

伸长的动画已经成型了,那缩短的动画不就简单了,直接动画reverse不就好了?我激动得设置了:

valueAnimator = new ValueAnimator().ofFloat(0, mMaxProgress,0);

或者是

valueAnimator.setRepeatMode(ValueAnimator.REVERSE);

我迫不及待的运行了代码,卧草草,竟然不行?仔细观察效果,我们发现了问题:

如果是缩短,还是从顺时针的头部缩短,而不是从尾部,这是为什么呢?其实从api也可以理解,因为我们是从起始位置开始画弧,只要起始位置不变,尾部肯定不会发生变化。

虽然明白了这个道理,但是心情非常的压抑,难道就要放弃了?突然灵光一闪,我发现了一个神奇的办法,不知道机智的小伙伴是不是也想到了:

还记得我之前的绘图步骤吗?

先绘制进度部分,然后剩余部分不全。

既然进度部分只能头部伸长,尾部也是一样,那我让补全部分伸长,那进度部分的尾部不就是缩短了吗?

那如何让补全部分伸长呢?

1、把progress在伸长结束时,开始让补全部分使用progress,从而让他伸长,但是这样会改变原有的功能逻辑,非常危险,工作量也大。

2、最简单的办法,把进度的颜色不补全部分的颜色交换,然后把位置也互换,不就OK了?

经过简单的修改之后:

if (valueAnimator == null) {

valueAnimator = new ValueAnimator().ofFloat(0, mMaxProgress);

valueAnimator.setDuration(DURATION);

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator valueAnimator) {

float value = (float) valueAnimator.getAnimatedValue();

setProgress(value);

}

});

valueAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animator) {

}

@Override

public void onAnimationEnd(Animator animator) {

// 因为是循环动画,所以这里不会回调

}

@Override

public void onAnimationCancel(Animator animator) {

}

@Override

public void onAnimationRepeat(Animator animator) {

// 互换两者的颜色

int color = getProgressBackgroundColor();

setProgressBackgroundColor(getProgressColor());

setProgressColor(color);

}

});

}

valueAnimator.setRepeatCount(-1);

valueAnimator.start();

ok,还有谁?最关键的部分已经全部完成了,还差最后一点点,仔细的观察效果图,发现进度条是有最小进度的,没有完全消失,所以我们再设置一个最小进度,并且每次设置进度的时候,我们都稍微旋转一下角度,这样就会一边伸长缩短一边旋转了:

/**

* 开始过度动画

*/

private void startIntermediateAnim() {

if (valueAnimator == null) {

valueAnimator = new ValueAnimator().ofFloat(mMinProgress, mMaxProgress - mMinProgress);

valueAnimator.setDuration(DURATION);

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator valueAnimator) {

float value = (float) valueAnimator.getAnimatedValue();

setProgress(value);

// 每次旋转2度

mStartAngle += 2;

}

});

valueAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animator) {

}

@Override

public void onAnimationEnd(Animator animator) {

}

@Override

public void onAnimationCancel(Animator animator) {

}

@Override

public void onAnimationRepeat(Animator animator) {

// 因为有了最小进度,所以每次都要位置设置到补全部分的位置

mStartAngle = mStartAngle - CIRCULAR / mMaxProgress * mMinProgress;

// 互换两者的颜色

int color = getProgressBackgroundColor();

setProgressBackgroundColor(getProgressColor());

setProgressColor(color);

}

});

}

valueAnimator.setRepeatCount(-1);

valueAnimator.start();

}

最终的效果,就想一开始的效果图一样,这里不贴了。

总结#

看上去稍微有点复杂的动画,经过我们的分析拆解,就变得很简单了。如果是利用Translation, Rotate 这样的动画,那实现起来真是太难了,ValueAnimator就是从他们中分离出来的专门用来计算差值的强大武器,有了它我们开发一些高级的效果,就简单多了。

我对demo进行了一些修改,即可以是普通的圆形进度条,也可以是loading的动画,就想progressBar一样,大家可以下载下来,参考一下。

ok,今天就到这里了,明天就是周末了,祝大家浪起来~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python没有那个文件或目录_fatal error: Python.h: 没有那个文件或目录 解决方法

今天安装scrapy 先说下环境 Ubuntu16.04 系统默认Python 2.7.12 (default, Nov 19 2016, 06:48:10) ,安装过anaconda(很关键,里面有好多系统包,也是为什么此工具不十分依赖系统环境的原因,否则单独装matplotlib也是难弄…

1-7docke的网络模式

1、Bridge模式bridge 模式是 docker 的默认⽹络模式,不写 –net 参数,就是 bridge 模式。比如使⽤ docker run - p 时工作模式从网上找了一个,如下 例子: run -it -d --name test1 --netbridge centos:v1 bashrun -it -d --name t…

[html] HTML5的video怎么取消自动播放?

[html] HTML5的video怎么取消自动播放? 去掉 autoplay 属性个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

分页的limit_分页场景(limit,offset)为什么会慢

链接:http://t.cn/AidABz08从一个问题说起五年前在腾讯的时候,发现分页场景下,mysql请求速度非常慢。数据量只有10w的情况下,select xx from 单机大概2,3秒。我就问我师父为什么,他反问“索引场景,mysql中获…

[html] 隐藏div内文字的方法有哪些?

[html] 隐藏div内文字的方法有哪些? text-indent:-9999px; 或 line-height:0; font-size:0; overflow:hidden;个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端…

Android游戏开发基础part3--Paint 画笔

游戏开发基础part3--Paint 画笔 Paint画笔是绘图的辅助类,一般它是作为画布的参数来实现相应的效果,Paint类中包含文字与位图的样式、颜色等属性信息。Paint的常用方法如下: 1.setAntiAlias(boolean aa) 作用:设置画笔是否无锯齿 …

jvm 参数_6个提高性能的JVM参数

截止到2020年五月,JVM中仅仅只是关于垃圾回收和内存相关的参数就已经超过600个。如果算上其他方面的参数,JVM相关的总参数能轻松超过1000个。参数太多了,弄得人很懵逼。在这边文章中,我们只选取了7个比较重要,且有用的…

zabbix入门之定义触发器

zabbix入门之定义触发器 触发器的概念 触发器的定义:界定某特定的item 采集到数据的非合理区间或非合理状态。通常为逻辑表达式。 逻辑表达式(阈值):通常用于定义数据的不合理区间,其结果如下: O K (符合条件&#xff…

linux重启memcache_Linux中安装Memcached服务的方法

Linux中安装Memcached服务的方法导语:在Linux中安装Memcached服务需要执行一些命令行,下面就由小编为大家介绍一下Linux中安装Memcached服务的方法,大家一起去看看吧!下载并安装Memcache服务器端服务器端主要是安装memcache服务器…

[html] 说说页面中字体渲染规则是怎样的?会有哪些因素影响字体的渲染?

[html] 说说页面中字体渲染规则是怎样的?会有哪些因素影响字体的渲染? 字体渲染: 1.解码,根据web服务器返回的(或者本地网页本身的)content-type charset等信息确定编码,将网页解码成Unicode字…

mybatis字符串转成数字_Python字符串三种格式化输出

字符串格式化输出是python非常重要的基础语法,今天就把三种格式化输出做一个简单的总结,希望对大家有帮助。格式化输出:内容按照一定格式要求进行输出。1.使用占位符%输出python2.6版本之前,使用%格式化字符串沿用的是C语言的输出…

eclipse dorado plugin

http://lindows.iteye.com/blog/224004 下载中心 http://www.bstek.com/downloadcenter.htm dorado debug shutcut page time:CtrlShiftF12 bstekIDE Eclipse插件扩展点应用介绍 http://macrochen.iteye.com/blog/138625 BstekIDE_1.2.2_Installer.jar http://www.bstek.com/do…

[html] 如何构建“弱网络环境”友好的项目?

[html] 如何构建“弱网络环境”友好的项目? 采用PWA技术个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

[html] 举例说明锚点定位有什么作用?

[html] 举例说明锚点定位有什么作用? 我能想象到的一种应用场景: 一、我们在做一个很长的网页时,需要在页面内做一个导航,点击导航里的链接不是新开一个窗口或者跳转到其他网址,而是跳转到当前页的某一个位置。那么所要跳转到的那…

逆反过程的学习会如何

C#工作已三年了,突然的一天头脑一热就去买了几本C/C语言的书,准备冲实下自已,但不知这个学习的过程会不会不适应呢。因为这是个逆反的过程吧!我是这么认为的。记得从不懂oracle到入门只用了一个星期的时间,现在也只能算是个中上的…

android真机调式问题之offline target

用cmd命令进入android-sdk-windows\platform-tools目录, adb kill-server; adb start-server; 然后USB断下重连,以前的解决办法是重启手机。。。转载于:https://www.cnblogs.com/bvin/archive/2012/06/21/2557709.html

三个不等_2道真题,讲透「基本不等式」的使用原则 | 真题精讲-11

「不等式」和「最值」之间有着非常天然的强联系;基本不等式有3个非常明显的形式特征;知识点的用法比知识点本身更重要。先发福利:这里有6场「高考数学」系列Live的讲义,全拿去,送给你——《高考数学:免费送…

[html] 编写html时,你有没有用过Emmet插件呢?说说它的优点及规则有哪些?

[html] 编写html时,你有没有用过Emmet插件呢?说说它的优点及规则有哪些? 用过,vscode编辑器自带支持Emmet语法; 它可以帮助快速编写HTML代码,减少复制粘贴的操作; 常见规则: 1. >…

python web自动化测试实验报告_Python:web自动化测试

用selenium包。# -*- coding: utf-8 -*-# 说明: 当前的浏览器驱动用的是edge浏览器.# 需要下载浏览器驱动,并把它的路径添加到环境变量from selenium import webdriverimport timedriver webdriver.Edge()homepage_url http://10.180.10.93:8000/driver.get(homepage_url)dri…

[html] 怎样去除iOS和Android中的输入URL地址的控件条呢?

[html] 怎样去除iOS和Android中的输入URL地址的控件条呢? setTimeout(scrollTo,0,0,0);个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题