Android动画——仿vivo X6闪充动画效果
做程序猿这么久一直没有写博客,是不正常的,故以此为第一篇博客,开始我的博客生涯。
前不久,看到一篇博客,关于X6闪充动画的效果,是一个叫什么“瓶子盖子”写的,暂时就叫这个名字吧,具体名字没记清(sorry)。跑了一下他的代码,发现各种卡顿。。。一查他的代码发现,在死循环里面不停地new Message(),不卡有鬼了。。。当然,我并没有对他有不敬的意思,只是想改良一下效果。
先上vivo X6闪充真机效果图:
充电时会不停地旋转,效果绚丽。
下面讲讲实现原理:
该动画实际上是由四条弧线,和中间的带线条的圆形组成。android里面给了画弧线的方法canvas.drawArc()。这个不难,难的是里面的圆圈带线条。其实“瓶子盖子”的那个方案很不错(给他个赞),画72条线,通过画面的旋转,使得各条线达到对应的位置,下面是代码:
/*** 绘制内切圆和锯齿,通过canvas的旋转,画出对应的锯齿线* @param canvas*/
private void drawCircle(Canvas canvas) {float radius = HEIGHT - (HEIGHT * 0.3f) * 2 - (WIDTH * 0.17f);canvas.drawCircle(WIDTH / 2, HEIGHT / 2, radius, mInCrilePaint);canvas.save();for (int i = 0; i < 72; i++) {if (i >= mProgress) {mInLine.setColor(Color.parseColor("#555555"));} else {mInLine.setColor(Color.parseColor("#00ff00"));}canvas.drawLine(WIDTH / 2, HEIGHT / 3.7f, WIDTH / 2, HEIGHT / 3.7f + HEIGHT * 0.05f , mInLine);canvas.rotate(5, getWidth() / 2, getHeight() / 2);}
}
静态的显示效果出来了,但是还缺少动画效果。“瓶子盖子”的跑动画是通过一个死循环,去跑动画,实现完全可以不用这么做。
安卓里面已经提供了Animator来帮助我们实现动画效果。
事实上,我们可以通过Animator的setRepartCount(-1)来实现无限循环。我猜想,vivo的攻城狮也大致是这样写的吧。
下面贴下代码:
mAnimator = ValueAnimator.ofFloat(0, 1);
mAnimator.setDuration(1500);
mAnimator.setInterpolator(new LinearInterpolator());
mAnimator.setRepeatCount(Animation.INFINITE);
mAnimator.addUpdateListener(this);
整体思路:
1.首先创建一个新的类FlashChargeView继承View,实现动画的监听,以监听到动画变化。在该view的构造方法里,创建一个ValueAnimator,初始化该Animator,使其无限循环播放。提供给外部的只有三个方法:开始播放动画、停止播放动画、设置当前电量。具体代码:
/*** Created by Jxr33 on 2016/8/23.*/
public class FlashChargeView extends View implements ValueAnimator.AnimatorUpdateListener {/** 细线,粗线,圆,圆内进度,文字的画笔 */private Paint mPaintSmall, mPaintBig, mInCrilePaint, mInLine, mTextPaint;/** 控件的高宽 */private static float WIDTH, HEIGHT;/** 动画 */private ValueAnimator mAnimator;/** 圆弧起始角度 */private float startAngle = 0;/** 圆弧旋转角度 */private float offset = 0;/** 当前电量 */private int mCurrPower = 70;/** 当前电量的进度 */private float mProgress;public FlashChargeView(Context context) {super(context);init();}public FlashChargeView(Context context, AttributeSet attrs) {super(context, attrs);init();}public FlashChargeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mPaintSmall = new Paint();mPaintSmall.setAntiAlias(true);mPaintSmall.setStrokeWidth(5);mPaintSmall.setStyle(Paint.Style.STROKE);mPaintSmall.setColor(Color.parseColor("#12ADFF"));mPaintBig = new Paint();mPaintBig.setAntiAlias(true);mPaintBig.setStrokeWidth(20);mPaintBig.setStyle(Paint.Style.STROKE);mPaintBig.setColor(Color.parseColor("#12ADFF"));mInCrilePaint = new Paint();mInCrilePaint.setAntiAlias(true);mInCrilePaint.setStrokeWidth(.5f);mInCrilePaint.setStyle(Paint.Style.STROKE);mInCrilePaint.setColor(Color.parseColor("#eeeeee"));mInLine = new Paint();mInLine.setAntiAlias(true);mInLine.setStrokeWidth(3);mInLine.setColor(Color.parseColor("#00ff00"));mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setStrokeWidth(3);mTextPaint.setTextSize(80);mTextPaint.setColor(Color.parseColor("#ffffff"));mAnimator = ValueAnimator.ofFloat(0, 1);mAnimator.setDuration(1500);mAnimator.setInterpolator(new LinearInterpolator());mAnimator.setRepeatCount(Animation.INFINITE);mAnimator.addUpdateListener(this);this.mProgress = mCurrPower * 72.0f / 100;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);WIDTH = w;HEIGHT = h;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawOutArc1(canvas);drawOutArc2(canvas);drawOutArc3(canvas);drawOutArc4(canvas);drawCircle(canvas);drawCircleIn(canvas);drawText(canvas);}/*** 绘制文字* @param canvas*/private void drawText(Canvas canvas) {float textSize = mTextPaint.measureText(mCurrPower + "%");float x = WIDTH / 2 - textSize / 2;float y = HEIGHT / 2 + textSize / 5;canvas.drawText(mCurrPower + "%", x, y, mTextPaint);}/*** 绘制最里面的圆* @param canvas*/private void drawCircleIn(Canvas canvas) {float radius = (float) (HEIGHT - (HEIGHT * 0.3) * 2 - (WIDTH * 0.22));canvas.drawCircle(WIDTH / 2, HEIGHT / 2, radius, mInCrilePaint);canvas.save();}/*** 绘制内切圆和锯齿,通过canvas的旋转,画出对应的锯齿线* @param canvas*/private void drawCircle(Canvas canvas) {float radius = HEIGHT - (HEIGHT * 0.3f) * 2 - (WIDTH * 0.17f);canvas.drawCircle(WIDTH / 2, HEIGHT / 2, radius, mInCrilePaint);canvas.save();for (int i = 0; i < 72; i++) {if (i >= mProgress) {mInLine.setColor(Color.parseColor("#555555"));} else {mInLine.setColor(Color.parseColor("#00ff00"));}canvas.drawLine(WIDTH / 2, HEIGHT / 3.7f, WIDTH / 2, HEIGHT / 3.7f + HEIGHT * 0.05f , mInLine);canvas.rotate(5, getWidth() / 2, getHeight() / 2);}}/*** 绘制最外层弧线* @param canvas*/private void drawOutArc1(Canvas canvas) {RectF mRectF = new RectF(WIDTH * 0.1f, WIDTH * 0.1f, WIDTH * 0.9f, WIDTH * 0.9f);canvas.drawArc(mRectF, startAngle + offset, 200, false, mPaintSmall);}/*** 绘制外层的第二条弧线* @param canvas*/private void drawOutArc2(Canvas canvas) {RectF mRectF = new RectF(WIDTH * 0.14f, WIDTH * 0.14f, WIDTH * 0.85f, WIDTH * 0.85f);canvas.drawArc(mRectF, -(startAngle + offset), 150, false, mPaintBig);}/*** 绘制外层第三条弧线* @param canvas*/private void drawOutArc3(Canvas canvas) {RectF mRectF = new RectF(WIDTH * 0.22f, WIDTH * 0.22f, WIDTH * 0.795f, WIDTH * 0.795f);canvas.drawArc(mRectF, startAngle + offset - 90, 110, false, mPaintSmall);}/*** 绘制外层第四条弧线* @param canvas*/private void drawOutArc4(Canvas canvas) {RectF mRectF = new RectF(WIDTH * 0.255f, WIDTH * 0.255f, WIDTH * 0.75f, WIDTH * 0.75f);canvas.drawArc(mRectF, -(startAngle + offset + 150), 150, false, mPaintBig);}/*** 开始播放闪充动画*/public void startChargeAnimator() {if (mAnimator != null) {mAnimator.start();}}/*** 停止闪充动画*/public void endChargeAnimator() {if (mAnimator != null) {mAnimator.cancel();}}/*** 设置当前电量* @param power*/public void setPower(int power) {this.mCurrPower = power;this.mProgress = power * 72.0f / 100;}@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float fraction = animation.getAnimatedFraction();this.offset = 360 * fraction;this.invalidate();}
}
2.在布局文件layout里,引用该View:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000000"tools:context="com.vivo.flashcharge.MainActivity"><com.vivo.flashcharge.FlashChargeViewandroid:id="@+id/chargeView"android:layout_width="180dip"android:layout_height="180dip"android:layout_centerInParent="true"/></RelativeLayout>
3.Activity里引用该layout,并开始播放动画,设置当前电量。(这里用到了ButterKnife插件,该插件封装了findViewById等方法,具体以下再讲):
public class MainActivity extends AppCompatActivity {@BindView(R.id.chargeView)FlashChargeView chargeView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);chargeView.startChargeAnimator();chargeView.setPower(90);}}
好了,具体效果开发完成了。这里我用的开发工具是Android Studio,很方便很快捷。
最后,得感谢下“瓶子盖”,没有他,我的第一篇博客也不知道要到什么时候才会诞生。估计以后会写更多的博客,大家一块交流嘛~~
Github路径:https://github.com/jxr202/VivoFlashCharge
不积跬步,无以至千里。。。
Android动画——仿vivo X6闪充动画效果相关推荐
- 直播app源代码 直播软件开发Android UI动画 仿直播点赞飘心动画效果
直播app源代码 直播软件开发Android UI动画 仿直播点赞飘心动画效果 一个飘心的小动画,之前看也看到网上有很多轮子,但是感觉不是很符合我的需求,所以自己就凑活凑活搞出来一个,废话不多说先看图 ...
- 今日力推: Android 高仿哔哩哔哩动画客户端 / Android MD版的花瓣网App
一.CardSwipeLayout 仿探探卡片滑动效果的布局 链接: http://pan.baidu.com/s/1qYApDfQ 密码: fz3q 二.Android高仿哔哩哔哩动画客户端bili ...
- android 仿 动画,Android动画 - 仿58同城加载动画
Android动画 - 仿58同城加载动画 效果图 58LoadingView.gif 分析动画 首先分析动画,如上图所示: 动画分为三部分,分别为上方跳动部分,中间阴影部分,和下方文字部分. 上方跳 ...
- android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果
本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...
- com.android.vovo,Android仿ViVO X6 极速闪充动画效果
一直都在看自定义View,经过一个星期的坚持,基本上能够写出一些比较实用的控件效果了,今天天气太热,就待在家里玩手机,然后手机没电了,在充电的时候,看到了手机的充电动画,觉得挺酷,然后自己我就仔细的分 ...
- Android 抖音爱心动画,Android动画 - 仿抖音加载动画
在地铁中刷抖音,由于网络不通畅加载很慢,抖音会加载一个加载动画,感觉很有意思,于是分析了一下,自己写了Demo,实现效果. 效果图 分析动画 首先分析动画,初始状态是由两个相切的圆形图案组成. 将动画 ...
- 卷起来了!Android OpenGL仿自如APP裸眼3D效果
/ 今日科技快讯 / 近日,"乘联会"微信公众号发布消息,2021年12月新能源乘用车市场多元化发力,厂商批发销量突破万辆的企业有14家,较前期大幅增多,其中:比亚迪933 ...
- Android OpenGL 仿自如 APP 裸眼 3D 效果
概述 之前看到 自如团队 发布的 自如客APP裸眼3D效果的实现 ,非常有趣,不久后,社区内 Android 的开发者们陆续提供了 Flutter. Android 原生 .Android Jetpa ...
- Android实现仿360手机卫士悬浮窗效果
大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...
最新文章
- 关于并发处理,下列哪些说法符合《阿里巴巴Java开发手册》
- poj3565(最大权完美匹配)
- 如何像算法工程师一样,看待这个世界?
- IDEA显示Run Dashboard窗口,Multiple Spring Boot run configurations were detected. Run Dashboard allows to
- 控制面板项 .cpl 文件说明
- 计算机控制系统EHA,优·计算机控制技术第四章.doc
- 《大数据》再获新荣誉——“综合性人文社会科学”学科最受欢迎期刊
- ubuntu 下安装和启动SSH 服务
- linux命令五十七之tar命令;linux多个文件压缩打包到一个压缩文件
- 黎曼猜想 量子计算机,理解黎曼猜想(一)背景
- [论文笔记]Vision-based Control of 3D Facial Animation
- 【机器学习百科全书目录】PRML ESL MLAPP 西瓜书 花书 RLAI 统计学习方法 蒲公英书
- 【建议背诵】2022下半年软考「高项」100题(2)
- python爬虫从企查查获取企业信息-手工绕开企查查的登录验证
- 从子窗口中获取父窗口的句柄例子
- 安卓手机手电筒不见了?
- 1176: 【入门】买蛋糕
- 一个著名的调度系统是怎么设计的?
- ubuntu系统输入法切换_Ubuntu 安装中文输入法 小白版
- 【网络安全】Xss漏洞