场景:点击桌面图标,图标放大,然后圆形进度旋转一圈结束,时间可控~~~

先理一下,启动”桌面动画”app,第一次启动在launcher上创建一个”点我点我”快捷图标,点击这个图标,动画开始!

1.创建桌面图标

 public class App extends Application {private static Context context;public static Context getContext() {return context;}public void onCreate() {super.onCreate();context = this;if (Config.getIsFirstLaunch()) {Intent intent = new Intent();intent.setClass(this, LauncherActivity.class);intent.setAction("com.snow.action.start");ShortcutUtils.buildShortcut("点我点我", R.drawable.widget, intent, this);Config.setIsFirstLaunch(false);}}
}

创建的时候用了一个异步线程,交给ScheduledThreadPoolExecutor执行器,首先要判断一下图标是否存在,创建过程:
给launcher发消息

    private static boolean addShortcut(String name, int iconId, Context context, Intent intent) {Intent intent1 = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");intent1.putExtra("duplicate", false);intent1.putExtra("android.intent.extra.shortcut.NAME", name);intent1.putExtra("android.intent.extra.shortcut.ICON", BitmapFactory.decodeResource(context.getResources(),iconId));intent1.putExtra("android.intent.extra.shortcut.ICON_RESOURCE", Intent.ShortcutIconResource.fromContext(context, iconId));intent1.putExtra("android.intent.extra.shortcut.INTENT", intent);intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);//65536context.sendBroadcast(intent1);return true;}

一条权限:

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

好啦,点击图标,LauncherActivity启动,这个Activity是singleInstance单例模式,然后关键一点,主题配置成透明样式

    <style name="Transparent" parent="@style/Theme.AppCompat"><item name="android:windowBackground">@android:color/transparent</item><item name="android:windowNoTitle">true</item><item name="android:windowIsTranslucent">true</item><item name="android:windowAnimationStyle">@null</item><item name="android:actionBarStyle">@null</item><item name="actionBarStyle">@null</item></style>

接着看下布局

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/root"android:layout_width="match_parent"android:layout_height="match_parent"><com.snow.cc.views.CircleAnimView
        android:id="@+id/rocket_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/widget" /></RelativeLayout>

没错就是一个相对布局,加一个自定义view.
widget是她的背景图,也就是火箭

问题来了,既然是相对布局,而动画效果,是背景图刚好在桌面icon的正上方(Z轴上来说),感觉就是桌面图标自己在变化,其实不然,只是公用了一个图片而已,那么怎么调整rocket_view的位置呢?

Rect rect = intent.getSourceBounds();//获取icon坐标信息
这里,桌面启动的时候,Launcher会通过setSourceBounds方法,设置图标的坐标信息并通过Intent发送出去,原来Launcher这么会玩…

有了Rect就可以调整rocket_view的位置了,考虑StatusBar的高度

    private RelativeLayout.LayoutParams computeAnimationIconLayoutParams(View icon, Rect rect) {RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) icon.getLayoutParams();layoutParams.topMargin = rect.top - this.getStatusBarHeight();layoutParams.leftMargin = rect.left;layoutParams.width = rect.right - rect.left;layoutParams.height = layoutParams.width;return layoutParams;}

好了,进入动画知识了

rocketView.startAnimation(360, new Animation.AnimationListener() {@Overridepublic void onAnimationEnd(Animation animation) {finish();//动画结束,自己退出overridePendingTransition(0, 0);}...});

360度刚好一圈,结束了,使命就完成了额~~~

自定义CircleAnimView继承自View

这里扫描角从0度到360度,借助了动画api

   class OpenAnimation extends Animation {float sweepAngle;public OpenAnimation(int sweepAngle, long duration) {super();this.sweepAngle = ((float) sweepAngle);this.setDuration(duration);this.setInterpolator(new AccelerateDecelerateInterpolator());}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {CircleAnimView.this.currentAngle = this.sweepAngle * interpolatedTime;CircleAnimView.this.invalidate();Log.e(TAG, "OpenAnimation :" + interpolatedTime + "  " + currentAngle);...}}

在绘制Animation的过程中会反复的调用applyTransformation函数,每次调用参数interpolatedTime值都会变化,从0渐 变为1,当该参数为1时表明动画结束。通过参数Transformation 来获取变换的矩阵(matrix),通过改变矩阵就可以实现各种复杂的效果。

但是这里只关心interpolatedTime,初始话的时候sweepAngle扫描角度为360度,当然是可控的

rocketView.startAnimation(360, new Animation.AnimationListener() {...});

动画的插值器指定为AccelerateDecelerateInterpolator:

/* An interpolator where the rate of change starts and ends slowly but * accelerates through the middle. */

在动画开始与结束的地方速率改变比较慢,在中间的时候加速

每次计算当前扫描角度,然后invalidate(),会引起View的
onDraw(Canvas canvas) 方法调用,那我们就在这个方法里根据当前弧度计算圆弧和小白点的位置:

    private void computePosition() {int w = ((int) ((((double) this.getWidth())) * RATE_CIRCLE));//进度环所在区域宽度int h = ((int) ((((double) this.getHeight())) * RATE_CIRCLE));//进度环所在区域高度int diameter = w > h ? h : w;//调整圆环的直径this.centerX = ((float) (this.getWidth() / 2));//中心点xthis.centerY = ((float) (this.getHeight() / 2));//中心点ythis.radius = ((float) (diameter / 2));//圆环的半径this.endPointRadius = ((int) ((((double) this.radius)) * RATE_RADIUS_ENDPOINT));//小白球的半径this.paintWidth = ((int) ((((double) this.radius)) * RATE_RADIUS_PAINT_WIDTH));this.left = this.centerX - this.radius;//圆环的左边距this.right = this.centerX + this.radius;//圆环的右边距this.top = this.centerY - this.radius;//圆环的顶边距this.bottom = this.centerY + this.radius;//圆环的底边距}

位置,尺寸都有了,就可以用画笔画了:
画圆弧进度

canvas.drawArc(new RectF(this.left, this.top, this.right, this.bottom), ZERO_ANGLE, this.currentAngle,false, this.progressPaint);

画小白球

     private void drawProgressBarPoint(Canvas canvas) {float angle = inOpeningAnimation ? currentAngle : endAngle;this.endX = (float) Math.sin(Math.toRadians(angle)) * radius + centerX;this.endY = (float) Math.sin(Math.toRadians(angle) - Math.PI / 2) * radius + centerY;canvas.drawCircle(endX, endY, ((float) endPointRadius), endPointPaint);//1.570796}

这里要把角度转换成对应的弧度值,靠Math.toRadians这个方法了
再回顾一下弧度和角度,我发现这些都还给数学老师了@~@

它们的关系可用下式表示和计算: 角(弧度)= 弧长/半径
圆的周长是半径的 2π倍,所以一个周角(360度)是 2π弧度。 半圆的长度是半径的 π倍,所以一个平角(180度)是 π弧度。

定了中心点和半径,有了画笔,就drawCircle啦!!!

项目戳这里:
https://github.com/shonegg/DesktopCircleAnimation

android桌面动画相关推荐

  1. android 桌面动画,Android 如何在Launcher的桌面滑动时添加动画效果? M

    正文 目前的Launcher桌面滑动时,是没有动画的.如何在Lancher的桌面滑动时添加动画效果?Demo: 请修改Workspace.java的screenScrolled方法,如下: @Over ...

  2. android桌面相框,桌面动画相框小工具

    桌面动画相框Widget+(Animated Photo Frame Widget +),创造属于您独立的桌面播放照片小工具,不同于以往的照片工具,我们提供了多达30多个种类的独特相框及7种播放照片动 ...

  3. Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现

    这次我们将代码的重点放在火箭升空的效果上,因此简单起见,就直接在模仿360手机卫士悬浮窗的那份代码的基础上继续开发了,如果你还没有看过那篇文章的话,建议先去阅读 Android桌面悬浮窗效果实现,仿3 ...

  4. android图形动画

    学习View的时候看到的,记录下 Android图形动画 作者 朱才:http://cnblogs.com/zhucai/ 朱才 微博:http://weibo.com/zhucai 2017/8/1 ...

  5. Android桌面管理

    引言 Android系统提供了一个桌面-也就是用户启动后第一次看到的页面,如下图.从图中可以看出,桌面的作用类似于PC的桌面,桌面上放置一些常用的程序和功能. 在Android桌面上首先看到的是壁纸, ...

  6. android 自定义loading,Android自定义动画-StarLoadingView

    今天来分享第二个自定义loading的动画,起了个名字叫 蹦跶的星星 ,还是老规矩先介绍,后上图. 实现效果在最后,GIF有点大,手机流量慎重. 介绍 首先声明做这个动画的初衷是为了学习和分享,所以从 ...

  7. android 三维动画效果,9款令人惊叹的HTML5 3D动画应用

    原标题:9款令人惊叹的HTML5 3D动画应用 之前我们已经向大家分享了很多HTML5动画应用了,大部分都非常炫酷,也有一小部分是很实用的.今天我们要向各位HTML5动画爱好者介绍更多的HTML5 3 ...

  8. 【学习笔记】Android视图动画学习

    2019独角兽企业重金招聘Python工程师标准>>> 1.Android View动画框架 Animation框架定义了透明度.旋转.缩放和位移几种常见的动画. 实现原理:每次绘制 ...

  9. android矢量动画 充电,android矢量动画

    android矢量动画! 直接来个例子就明白了!(这里我把与动画无关的属性都用-表示) 首先你要有个矢量图 比如这个矢量图xml文件叫"vector1",文件在res\drawab ...

最新文章

  1. 派工单系统 源码_「青鸟报修云」酒店设备报修管理系统
  2. android+动画队列,Android属性动画详解
  3. ddr4单颗粒最大_Zynq UltraScale +系列之“DDR4接口设计”
  4. 二十三、 爬取mzsock网站写真社区
  5. 既然参与,那就做好,我相信我们是最棒的!!!
  6. linux 定义快捷命令,Linux系统自定义快捷命令的详细说明
  7. 使用cmd-命令运行Java项目
  8. php 刷新腾讯云cdn
  9. 浏览器自动打开html怎么办,浏览器自动弹出网页怎么处理?开机自动弹出垃圾网页如何解决?...
  10. 感冒、咳嗽、发烧、腹泻、扁桃体炎是儿童常见病
  11. java专业考独立本科_复旦大学-计算机网络(独立本科B080709)(停考过渡)
  12. Structed Streaming(Continuous Processing报错):StreamingQueryException;java.util.NoSuchElementException
  13. ZOJ4043 : Virtual Singers
  14. Revit API之BoundingBoxXYZ的用法和剖面框(Section Box)
  15. 日常用语--征求意见
  16. htc t328w android4.0,Android4.0新机 HTC T328w仅售1999
  17. 边工作边学习的现实选择
  18. 爱立信联合SK电讯和宝马进行首次多车辆5G测试
  19. 百度ai 人脸识别 java_百度ai 接口 人脸识别
  20. EV录屏有很大电流音的解决方法

热门文章

  1. 6.网络安全渗透测试—[信息收集篇6]—[Email信息收集]
  2. 数学建模常见的综合评价方法及预测方法
  3. 计算机专业Java毕设怎么做
  4. Codeforces1696 C. Fishingprince Plays With Array
  5. 向人工盘点库存和物品说再见
  6. Axure旋转原件或图片
  7. Django Channels 个人对官方文档大概理解 及一些地方的作用
  8. Sulley环境搭建
  9. 回答几个很多人在问的问题,以及苏生不惑提供的服务
  10. HFDS 内部工作机制