一、前言

在现今App泛滥的市场上,各种App的功能都是你抄我的我抄你的时候,想做一个精品的App没有自己的风格,没有让用户眼前一亮的功能,或是效果的话都留步住用户了。随时都可以被其他应用替代。现今到处都喊着app简约而不简单,用户体验至上的年代,但有几个app能做到呢?可能当设计师想着想着就忘记了设计的初衷。

吐槽半天,今天来看一下乐动力的一个比较有意思的动画效果,觉得挺爽的,然后刚好又想熟悉一下Android动画的,就拿来练下手。

二、效果图

三、动画分解

1、中间一个变大变小的动画

2、上下两个箭头不停的旋转

3、左右两个小的图片不停地旋转并跟着自传就可以达到类似平移

4、上面分解为五个Imageview并重写ViewGroup达到自定义排列

四、代码

package com.spring.ledongli;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;public class GuideView extends ViewGroup {/*** 左边的图片*/private ImageView left;/*** 右边的图片*/private ImageView right;/*** 上面的图片*/private ImageView top;/*** 下面的图片*/private ImageView bottom;/*** 中间的图片  m*/private ImageView center;/*** 屏幕的宽度*/private int screenW;/*** 屏幕的高度*/private int screenH;public GuideView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}public GuideView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public GuideView(Context context) {super(context);init(context);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(screenW, screenH);}private List<Bitmap> bitmaps = new ArrayList<Bitmap>();private void init(Context context){left = new ImageView(context);left.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.day));bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.day));right = new ImageView(context);right.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.night));bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.night));top = new ImageView(context);top.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.up));bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.up));bottom = new ImageView(context);bottom.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.down));bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.down));center = new ImageView(context);center.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.animation_battery));bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.animation_battery));screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();screenH = ((Activity)context).getWindowManager().getDefaultDisplay().getHeight();this.addView(center);this.addView(left);this.addView(right);this.addView(top);this.addView(bottom);}private LinearInterpolator interpolator = new LinearInterpolator();@Overrideprotected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {//五个控件的布局center.layout(screenW/2-bitmaps.get(4).getWidth()/2, screenH/2-bitmaps.get(4).getHeight()/2,  screenW/2+bitmaps.get(4).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2);top.layout(screenW/2-bitmaps.get(2).getWidth()/2,screenH/2-bitmaps.get(4).getHeight()/2-bitmaps.get(2).getHeight()+bitmaps.get(2).getWidth()/2/4,screenW/2+bitmaps.get(2).getWidth()/2, screenH/2-bitmaps.get(4).getHeight()/2+bitmaps.get(2).getWidth()/2/4);left.layout(screenW/2-bitmaps.get(0).getWidth()*2-bitmaps.get(0).getWidth()/4, screenH/2-bitmaps.get(0).getHeight()/2,screenW/2-bitmaps.get(0).getWidth()-bitmaps.get(0).getWidth()/4, screenH/2+bitmaps.get(0).getHeight()/2);right.layout(screenW/2+bitmaps.get(1).getWidth()+bitmaps.get(1).getHeight()/4, screenH/2-bitmaps.get(1).getHeight()/2,screenW/2+bitmaps.get(1).getWidth()*2+bitmaps.get(1).getHeight()/4, screenH/2+bitmaps.get(1).getHeight()/2);bottom.layout(screenW/2-bitmaps.get(3).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2-bitmaps.get(3).getWidth()/2/4,screenW/2+bitmaps.get(3).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2+bitmaps.get(3).getHeight()-bitmaps.get(3).getWidth()/2/4);playCenter();playTop();playBottom();playLeft();playRight();}/*** 右边的动画*/private void playRight() {//混合动画AnimationSet animationSet = new AnimationSet(false);RotateAnimation rotateRight = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-right.getLeft(), Animation.ABSOLUTE, (right.getBottom()-right.getTop())/2);RotateAnimation rotateSelf = new RotateAnimation(0, -359, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);//播放时间rotateSelf.setDuration(10*1000);//播放加速的模式rotateSelf.setInterpolator(interpolator);//设置无限循环rotateSelf.setRepeatCount(-1);rotateRight.setDuration(10*1000);rotateRight.setRepeatCount(-1);rotateRight.setInterpolator(interpolator);animationSet.addAnimation(rotateSelf);animationSet.addAnimation(rotateRight);//播放混合动画right.startAnimation(animationSet);}/*** 左边的动画*/private void playLeft() {AnimationSet animationSet = new AnimationSet(false);RotateAnimation rotateLeft = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-left.getLeft(), Animation.ABSOLUTE, (left.getBottom()-left.getTop())/2);rotateLeft.setDuration(10*1000);rotateLeft.setInterpolator(interpolator);rotateLeft.setRepeatCount(-1);RotateAnimation rotateSelf = new RotateAnimation(0, -359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);rotateSelf.setDuration(10*1000);rotateSelf.setRepeatCount(-1);rotateSelf.setInterpolator(interpolator);animationSet.addAnimation(rotateSelf);animationSet.addAnimation(rotateLeft);left.startAnimation(animationSet);}/*** 下面的动画*/private void playBottom() {RotateAnimation rotateBottom = new RotateAnimation(0, 359,  Animation.RELATIVE_TO_SELF, 0.5f, Animation.ABSOLUTE,screenH/2-bottom.getTop());rotateBottom.setDuration(10*1000);rotateBottom.setInterpolator(interpolator);rotateBottom.setRepeatCount(-1);bottom.startAnimation(rotateBottom);}/*** 上面的动画*/private void playTop() {RotateAnimation  rotateAnimation = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-top.getLeft(), Animation.ABSOLUTE, screenH/2-top.getTop());rotateAnimation.setDuration(10*1000);rotateAnimation.setInterpolator(interpolator);rotateAnimation.setRepeatCount(-1);top.startAnimation(rotateAnimation);}/*** 中间的View动画播放*/private void playCenter() {AnimationSet animationSet = new AnimationSet(false);ScaleAnimation scaleSmall = new ScaleAnimation(1.0f, 0.6f, 1.0f, 0.6f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);ScaleAnimation scaleBig = new ScaleAnimation(1.0f, 5.0f/3, 1.0f, 5.0f/3,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);scaleBig.setDuration(2*1000);scaleBig.setInterpolator(interpolator);scaleSmall.setDuration(2*1000);scaleSmall.setStartOffset(2*1000);scaleSmall.setRepeatCount(-1);scaleSmall.setFillEnabled(true);scaleSmall.setFillAfter(true);scaleBig.setStartOffset(2*1000);scaleBig.setRepeatCount(-1);scaleBig.setFillEnabled(true);scaleBig.setFillAfter(true);scaleSmall.setInterpolator(interpolator);animationSet.addAnimation(scaleBig);animationSet.addAnimation(scaleSmall);center.startAnimation(animationSet);}}

五、遇到的问题

写这个小Demo主要的问题在两个小太阳的自传和中点循转的结合,这方面在网上的资料也比较少,自己做了几个尝试最终完成。要很好的理解pivotXType里的三种方式Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT、Animation.ABSOLUT,第一种多用于基于自己View的几分之几来定值,第二种是基于父控件来定位,第三种是绝对定位,图片的基点在右上角,然后算偏移的值定位旋转的中间。

六、项目地址

http://download.csdn.net/detail/hxc2008q/6931227

广告

最近搞了个微信公众号,为各种程序员枯燥的写码生活添加一些生活调料,

在等待编译的过程看一篇美丽的图文放松放松肌肉。希望各位看官赏脸关注一下

公众号:马桶上的哲学

读哲名理,提升逼格

android动画的实战篇------乐动力旋转动画相关推荐

  1. Android开发系列——实战篇5:自适应屏幕尺寸(超详细教程)

    在实战篇4中构建了界面之后,在模拟器中完好的布局,在实际下载到手机上的时候,却出现了布局不协调的问题. 在模拟器Nexus6上的布局界面: 在真机HUWEI P10 Plus上的布局界面: 在真机HU ...

  2. android scaleanimation动画,【Android动画九章】-RotateAnimation(旋转动画)和ScaleAnimation(尺寸动画)...

    [Android动画九章]-RotateAnimation(旋转动画)和ScaleAnimation(尺寸动画) public abstract class Animation extends Obj ...

  3. android 画圆弧动画,『Android自定义View实战』自定义带入场动画的弧形百分比进度条...

    写在前面 这是在简书发表的处女座,这个想法也停留在脑海中很久了,一直拖到现在(懒癌发作2333),先自我介绍一番,一枚刚毕业不久的Android程序猿,初出茅庐的Android小生,之前一直在CSDN ...

  4. Android 自定义ViewGroup 实战篇 - 实现FlowLayout

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38352503 ,本文出自[张鸿洋的博客] 1.概述 上一篇已经基本给大家介绍了如 ...

  5. Android开发系列——实战篇11:多线程与异步机制

    本文介绍安卓的多线程与异步任务处理的机制 目录 一.多线程 1.主线程与子线程 2.Handler用法详解 使用Handler发送post请求 使用Handler处理Message消息 一.多线程 1 ...

  6. css 文字 3d旋转动画,CSS3 简单的三维文字旋转动画

    CSS 语言: CSSSCSS 确定 *, *:after, *:before { box-sizing: border-box; } html { height: 100vh; background ...

  7. android 圆动画效果,Android实现任意绕圆或椭圆旋转的动画——SatelliteAnimator使用介绍...

    话说实习也就快一个月了,虽然没干什么活,但是这几天总算是有一些可以写的东西. 代码中应该还存在很多问题要修改,大神们请赐教,不胜感激. 开始正题. 关于Android实现任意绕圆或椭圆旋转动画,我称之 ...

  8. 【Flutter 实战】17篇动画系列文章带你走进自定义动画

    老孟导读:Flutter 动画系列文章分为三部分:基础原理和核心概念.系统动画组件.8篇自定义动画案例,共17篇. 动画核心概念 在开发App的过程中,自定义动画必不可少,Flutter 中想要自定义 ...

  9. android 无限旋转动画,Android 属性动画之无限循环缩放动画,旋转动画

    缩放动画 AnimatorSet animatorSetsuofang = new AnimatorSet();//组合动画 ObjectAnimator scaleX = ObjectAnimato ...

最新文章

  1. 智源发布!《人工智能的认知神经基础白皮书》
  2. ×××视频下载:皮皮影视客户端功能使用
  3. WorkFlow入门Step.4—Adding Procedural Elements-For-WF4.0-(续)
  4. linux内核竞争条件漏洞,Linux内核竞争条件漏洞-导致远程代码执行
  5. java修改动态视频,直播视频app源码,动态修改cron
  6. Navicat Premium 12.0.24破解
  7. Nginx全局块的工作进程的两个指令
  8. 软件开发计划_敏捷软件开发实践:估算与计划读书笔记123第21章 关于计划的沟通...
  9. Springboot默认加载application.yml原理
  10. python 去除nan inf_Python实现半自动评分卡建模(附代码)
  11. 苹果html阅读器,设置Safari 10.0.2阅读器Reader字体
  12. 百度AI学习:二、语音合成
  13. 【f1c200s/f1c100s】不带中断引脚采用扫描的方式实现通用gpio-keys
  14. 非形式逻辑(04)因果关系和推理
  15. vue 渲染函数处理slot_Vue渲染函数详解
  16. ColdFusion CGI or Application variables
  17. 电脑快捷键快速关机方法,电脑如何快速关机
  18. jiaba库之关键词提取(增量更新自定义语料)
  19. Java8 默认垃圾回收器(GC)
  20. 抖音运营:抖音直播运营入门

热门文章

  1. 米家TVapp下载遇到的问题--https和http协议
  2. python排序算法——希尔排序(附代码)
  3. 新版微信强化短视频还可能做直播,会让秒拍陌陌们颤抖吗?
  4. 2020考研第一步:基本信息须知
  5. 设计模式(八):Bridge桥接模式 -- 结构型模式
  6. TI低功耗DCDC汇总找不同
  7. vue路由传参的方式
  8. 绘图软件有哪些免费使用操作
  9. Three.js初探之微信小游戏---第一篇
  10. Python对IP地址列表排序、对列表进行去重、IP地址与MAC地址组合的多个元组的列表排序,对列表内的元组升序和降序排序