原来学过用自定义控件以及视图动画来达到这个效果。后来根据慕课网的视频,接触到了属性动画,发现其精髓之处不是一点两点。

相信大家都知道,当我们在使用视图(View)动画的时候,改变轨迹时,所触发的点击事件却没有相对应的随之轨迹而改变。确切的说,Animation改变显示的位置,不可以实现交互的效果,只是实现了显示效果。

先看下Animator的介绍
This is the superclass for classes which provide basic support for animations which can be started, ended, and have AnimatorListeners added to them.
这是一个父类,什么的父类呢?一些对于动画可以提供启动,结束的类的父类,并且有可以对之实施监听事件。

第一重境界:ObjectAnimator (动画监听事件)

This subclass of ValueAnimator provides support for animating properties on target objects. The constructors of this class take parameters to define the target object that will be animated as well as the name of the property that will be animated. Appropriate set/get functions are then determined internally and the animation will call these functions as necessary to animate the property.
这个类是ValueAnimator的子类,为一些目标物体提供一些动画属性,这个类的构造函数将参数定义为将要动画的目标对象,可以使一些属性名称一样具体动画效果,set get获取,然后确定内部的东西,这些动画将调用这些功能来作为必要的动画属性。大体应该就是这个意思,本人英语水平low的很。

接下来我们先了解下属性动画ObjectAnimator,原理我也不会用语言去描述,通过简单的例子,看代码来了解通俗易懂。点击按钮,让图片做位移,旋转效果的实现。

先看下布局activity_main:

<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"
><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/imageview"android:onClick="click"android:src="@drawable/ic_launcher"/><Button android:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Move"android:onClick="move"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="58dp"/></RelativeLayout>

起初我们接触视图动画的时候,一般都用TranslateAnimation,RotationAnition等等了,复杂的动画效果用AnimationSet也能实现。

这里就不具体的讲解了,下面来看下属性动画ObjectAnimator是怎么实现。

ObjectAnimator提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。 当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束 动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法。

    ObjectAnimator.ofFloat(image, "rotation", 0F,360F).setDuration(1000).start();ObjectAnimator.ofFloat(image, "translationX", 0F,200F).setDuration(1000).start();ObjectAnimator.ofFloat(image, "translationY", 0F,200F).setDuration(1000).start();

虽然三个动画效果依次写出来,但并没有执行先后顺序,偏移XY的同时也在旋转着,并发执行。

既然存在ofxxx,我们可以使用PropertyValuesHolder这个类,它可以先将动画属性和值暂时的存储起来,后一起执行,在有些时候可以使用替换掉AnimatorSet,减少代码量。

    PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("rotation", 0F,360F);PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("translationX", 0F,200F);PropertyValuesHolder p3=PropertyValuesHolder.ofFloat("translationY",0F,200F);ObjectAnimator.ofPropertyValuesHolder(image, p1,p2,p3).setDuration(1000).start();

视图动画有AnimationSet,那我们的属性动画是不是也有一个set管理呢,答案是有的,AnimatorSet.

    ObjectAnimator animator1=ObjectAnimator.ofFloat(image, "rotation", 0F,360F);ObjectAnimator animator2=ObjectAnimator.ofFloat(image, "translationX", 0F,200F);ObjectAnimator animator3=ObjectAnimator.ofFloat(image, "translationY", 0F,200F);AnimatorSet set=new AnimatorSet();//可以试着调用不同方法,实现不同的动画效果//set.playTogether(animator1,animator2,animator3);//set.playSequentially(animator1,animator2,animator3);set.play(animator2).with(animator3);set.play(animator1).after(animator2);set.setDuration(1000);set.start();

在使用的过程中,可以试着set不同的实现顺序来看下效果,毕竟多联系下嘛。

属性动画的监听:

对于动画,一般都是一些辅助效果,比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束。

  public void click(View v) {ObjectAnimator animator = ObjectAnimator.ofFloat(v, "alpha", 0f, 1f);animator.setDuration(1000);animator.addListener(new AnimatorListener() {public void onAnimationStart(Animator animation) { // TODOAuto-generated method stub* * }* * @Override public void onAnimationRepeat(Animator animation) { // TODO* Auto-generated method stub* * }* * @Override public void onAnimationEnd(Animator animation) { // TODO* Auto-generated method stub Toast.makeText(MainActivity.this, "点击了",* Toast.LENGTH_SHORT) .show(); }* * @Override public void onAnimationCancel(Animator animation) { // TODO* Auto-generated method stub* * } });*/animator.start();
}

这里可以看出,再我们这样使用new AnimatorListener的时候,可以对动画的开始,重复,结束,取消都可以进行监听操作,可是我们有时候只希望监听动画结束或者单一状态的时,该怎么办呢?

那你可以使用AnimatorListenerAdapter

   public void click(View v) {ObjectAnimator animator = ObjectAnimator.ofFloat(v, "alpha", 0f, 1f);animator.setDuration(1000);animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {// TODO Auto-generated method stubsuper.onAnimationEnd(animation);Toast.makeText(MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();}});animator.start();
}

AnimatorListenerAdapter继承了AnimatorListener接口,然后空实现了所有的方法,当你想使用其中一个状态监听时,可以单一的重写该方法。这样减少了一定的代码量。

属性动画的初步了解应该差不多了,相信他们在阅读完以上部分应该对属性动画有了一定的了解,或许已经感觉到了和视图动画的区别。记得大家都应该知道一种菜单效果--->

ObjectAnimator实现卫星菜单效果

先看张效果图吧

当初接触过这个菜单的效果,是自定义控件的实现的,代码量挺复杂的,接触完属性动画,我就想是不是可以用它来完成这个效果呢?

接下来我们实现下,先看下布局,使用的FrameLayout

activity_main.xml:

<FrameLayout 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" ><ImageViewandroid:id="@+id/imageView_b"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="5dp"android:paddingTop="5dp"android:src="@drawable/b" /><ImageViewandroid:id="@+id/imageView_c"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="5dp"android:paddingTop="5dp"android:src="@drawable/c" /><ImageViewandroid:id="@+id/imageView_d"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="5dp"android:paddingTop="5dp"android:src="@drawable/d" /><ImageViewandroid:id="@+id/imageView_e"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="5dp"android:paddingTop="5dp"android:src="@drawable/e" /><ImageViewandroid:id="@+id/imageView_a"android:layout_width="wrap_content"android:layout_height="wrap_content"        android:src="@drawable/a" />
</FrameLayout>

布局效果图:

我们存放了5张图片,a图片为按钮图片,bcde则为卫星发射的菜单图。先把这些图片的id保存到数组中,方便我们统一的实例化。

private int[] res = { R.id.imageView_a, R.id.imageView_b, R.id.imageView_c,R.id.imageView_d, R.id.imageView_e };

新建一个List数组来存放这些图片。

  private List<ImageView> imageViewList = new ArrayList<ImageView>();

接下来,用循环遍历来实例化这些ImageView控件,把图片添加到imageViewList中,并实现这些菜单图片的监听事件。

 for (int i = 0; i < res.length; i++) {ImageView imageView = (ImageView) findViewById(res[i]);imageView.setOnClickListener(this);imageViewList.add(imageView);}

重写onClick方法,因为考虑到菜单要展开和收回两种状态效果。定义一个标志位,初始化为true.

private Boolean flag = true;// 用于判断展开 ,回收

点击事件方法:

@Override
public void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.imageView_a:if (flag) {startAnim();} else {closeAnim();}break;default:Toast.makeText(MainActivity.this, "click" + v.getId(),Toast.LENGTH_SHORT).show();break;}
}

一个展开动画效果的方法startAnim()和一个回收效果的方法closeAnim()。其实两者实现的动画效果是相反方向的。

startAnim()

 private void startAnim() {// TODO Auto-generated method stubfor (int i = 1; i < res.length; i++) {ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),"translationY",0F,(float) (300 * (Math.sin(Math.PI / 2 / (res.length - 2)* (i - 1)))));ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageViewList.get(i),"translationX",0F,(float) (300 * (Math.cos(Math.PI / 2 / (res.length - 2)* (i - 1)))));AnimatorSet set = new AnimatorSet();set.playTogether(animator, animator1);set.setDuration(300);set.start();set.setInterpolator(new BounceInterpolator());flag = false;}
}

实现了位移的偏移X,Y。其实没有多少复杂的,for循环遍历展开效果,只是在偏移的路径需要一些数学知识。这里我固定了偏移的半径,也就是水平或者纵向的最大偏移量为300.

掌握了这张图片的原理,应该就在以后的使用过程中得心应手了,不管展开的菜单个数为多少,可以根据数学算出XY偏移量即可。 相对于收回的动画方法,和展开的方法方向相反而已。
下载

属性动画实现卫星菜单效果相关推荐

  1. 属性动画实现旋转入场效果

    属性动画和硬件加速 日常杂谈 06月07日 首先,我感觉这部分内容真的挺无聊的,没有什么让人新奇的感觉.不过为了博客的整体性,我还是想随便整理一下相关的知识和内容. 一如既往,聊聊我的日常生活,最近可 ...

  2. flutter向上动画弹出菜单效果

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精. 重要消息[视频教程 感兴趣的伙伴可以瞅瞅] 本文章最后的效果如下: 如上图的效果,当点击菜单按钮时,子菜单向上动画弹出,然后当点击弹出 ...

  3. 王学岗的属性动画上(五)------抛物线效果的实现(估值器和插值器)

    布局文件只有一个<ImageView/> package com.example.propertyOfGang;import android.animation.Animator; imp ...

  4. 属性动画+贝塞尔曲线实现落叶效果~~~(@_@;)

    之前看了一款有点黄的17app底角的爱心各种乱飞,好奇这种效果的实现方式,恰巧看到这篇文章:程序亦非猿:一步一步教你实现Periscope点赞效果,遂按照其思路实现了一个落叶飘零的效果,如下动图: 实 ...

  5. android自定义弧形,Android 自定义弧形旋转菜单栏——卫星菜单

    概述 现在很多App会在入口比较浅的页面添加一些快捷操作入口,一方面是为了方便用户操作,一方面是为了提高产品一些关键入口的使用率,让用户能够在浏览信息流的过程中能快速切换至其他一些功能页面.例如豆瓣的 ...

  6. 用Canvas和属性动画造一只萌蠢的“小鬼”

    最近没事的时候想自己写一个支持下拉刷新,上拉加载的自定义View.写着写着,就觉得最常见的"一个圈转啊转"的进度条太普通了. 于是,就想看看有没有更有趣的一点的加载效果.在GitH ...

  7. android的优酷菜单,Android利用属性动画实现优酷菜单

    利用属性动画实现优酷菜单,供大家参考,具体内容如下 布局文件 xmlns:tools="http://schemas.android.com/tools" android:layo ...

  8. CSS3打造的10种创意动画菜单效果

    CSS3新增添了实现动画效果的新功能,通过本文,你可以对这些新功能有个初步了解.本文将为大家带来一些充满创意的菜单悬停效果.它由图标,主标题,副标题等简单的元素构成,通过CSS3最新的过渡(trans ...

  9. android 属性动画伸缩,Android的属性动画(二)加载框圆点旋转收缩放大缩小效果的实现...

    案例效果图如下, 案例实现步骤 1.首先用drawCircle()画好6个圆点 private void drawCircles(Canvas canvas) { //每个小圆之间的间隔角度 = 2π ...

  10. android属性动画作用范围,Android开发之动画效果浅析(一)

    程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...

最新文章

  1. 利用window.navigator.userAgent判断当前是否微信内置浏览器
  2. 卡尔曼滤波器原理和matlab实现
  3. Java Spring MVC model学习
  4. EDM营销之如何使邮件列表更加有效
  5. python有什么用-python有什么用
  6. 声明对象 和对象等于null的区别
  7. 如何下载sci论文?
  8. centos7设置键盘类型_CentOS7设置中文输入法
  9. Cesium屏幕坐标转世界坐标
  10. ajax响应速度慢,jQuery Ajax请求的响应速度变化
  11. 因特尔显卡自定义分辨率_如何在新版英特尔核芯显卡控制面板中自定义显示器分辨率...
  12. 计算机行业的未来10年发展前景,未来10年,这4大工作就业前景好,发展前途超过公务员...
  13. 图算法图神经网络归纳总结
  14. 生成领料单(编号:20110704A1153)
  15. 普通用户申请微软的OneDrive免费网盘,容量5T、5T、5T,重要事情说三遍!!!!!
  16. Windows下Ubuntu子系统,开启复制粘贴功能方法
  17. 2022年京东双十一和国庆哪个打折力度大?能优惠多少?
  18. IP-guard功能详解——安全U盘
  19. 23-TCP 协议(紧急标志)
  20. 长沙麻将APP思路整理

热门文章

  1. Excel判断身份证号码数据的第17或15位数字的奇偶性决定男女性别
  2. 计算机科学导论:第六章 计算机网络和因特网
  3. 名利双收的公益创业,“汇新杯”响应时代召唤助力公益创业
  4. Python中切片(Slicing)的运用(:运算符)
  5. Brownie Slicing
  6. 矩阵求导术(二)——矩阵对矩阵的求导
  7. Speedoffice(word)怎么撤回上一步的操作
  8. ubuntu java ide,在Ubuntu 18.04系统中下载与安装Eclipse IDE的方法
  9. PM Interview 60quiz
  10. 二元隐函数求二阶偏导_隐函数求二阶偏导