【Android】使用属性动画碰到的困惑及讲解
属性动画的教程网上已经特别多了,本篇也不打算再去各种详解知识点,主要就是记录题主学习属性动画时的碰到的一些困惑,以及后来自己的理解。如果有人也碰到相似的问题,正好可以一起讨论下。
概要
本篇主要涉及的知识点包括:
- ObjectAnimator
- ValueAnimator
老规矩,首先先来看下效果图:
这种折叠/展开,隐藏/显示的动画在很多地方都会有用到,如果再加上使用5.0后引进的Z属性,实现各种酷炫的立体动画就更吸引人了。所以,还是先掌握好这基础的属性动画吧。
分析
如果你还对属性动画不太明白,或者没用过ObjectAnimator、ValueAnimator的话,建议先去看下郭神的这篇。
从上图很容易可以看出,这需要用到translationX/Y属性,即平移的属性。也许你会觉得,这不是很简单吗,不就设置下平移的起止值,动画时长,搞定。
没错,是很简单,就是这么实现的。但其实,对于新手来说,知道怎么做和把它做出来其实还是两码事。题主也还是个初学者,当初也是觉得这很简单啊,然后自己做的时候却出现了各种问题。下面就来讲讲题主做的过程中碰到的一些问题吧。
1、平移的距离如何确定?
先来看那个竖直收缩/扩展的效果,每个控件都平移到最底下控件的位置,然后消失。有时候我们的需求就是这样,不要求将控件全部移出屏幕,只移到某个指定位置,然后消失之类的。如果是移出屏幕,那么距离很容易设定,但像这种情况下,我们要如何去设置每个控件应该平移多长的距离呢?
很多博客,在对属性动画介绍时,给出的示例代码都是简单的设置某个具体的数值,然后让我们看效果。但这里还能继续用写死的固定值吗,显然不行,那么就需要我们在代码中动态的来计算两个控件之间的距离,然后再来确定控件应该平移的距离。
经过一番查找,题主找到可以用View.getLocationOnScreen()这个方法来实现。
/**
* 计算两个view的距离
* @param v1
* @param v2
* @return 返回new int[2], [0]横坐标距离,[1]纵坐标的距离
*/
private int[] calculateWidgetsDistance(View v1, View v2){
int[] location1 = new int[2];
int[] location2 = new int[2];
int[] ret = new int[2];
v1.getLocationOnScreen(location1);
v2.getLocationOnScreen(location2);
ret[0] = Math.abs(location1[0] - location2[0]);
ret[1] = Math.abs(location1[1] - location2[1]);
return ret;
}
2、setTranslationX(float translationX) 参数值的含义
如果我们使用ValueAnimator来实现动画效果,那么我们就需要接触到setTranslationX()这类方法了,如下:
ValueAnimator animator = ValueAnimator.ofFloat(mView.getTranslationY(),300.0f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mView.setTranslationY(value);
}
});
animator.setDuration(1000);
animator.start();
那么好,问题来了。上面动画的效果是什么?或者说 300.0f代表的是什么含义?
先来说说动画的效果,是将mView从当前位置,沿Y轴平移到Y坐标300的地方?还是从当前位置沿Y正方向平移300?我们看下效果是什么:
好像是沿Y平移了300,那么真的是这样吗?如果上面代码的效果表示的意思真是从当前位置沿Y平移300,那么当我们再次点击按钮时,应该继续往下移300,不断的点击就不断的往下移才对,但很明显,从上图中我们看出,当再次点击时没有任何动画效果了。所以,上面代码的动画效果显然不是沿Y平移300.
那么到底是什么效果呢?我们来将代码稍微做些改动,先复制上面代码,然后把300.0f改成200.0f,然后把复制的这个动画绑定到其他按钮(如下图的FAB)上,这样当我们先点击FAB,再点击按钮本身,也就是先启动平移200f动画,再启动平移300f的动画。看看会有什么效果:
注意看上图里的点击顺序,为了更方便讲解,我们这里标好步骤:
- 点击FAB时,控件往下平移一段距离
- 再点击控件本身时,控件继续往下平移一段距离,但比第一次平移的距离短
- 然后不断点击按钮本身时,没任何动画效果
- 但是当再点击FAB时,按钮往上平移了
- 此时再点击按钮本身时,咦!发现有效果了,往下平移了
- 然后再点击按钮本身发现又没任何效果了。但是再点击FAB时,按钮又往上平移了!发现没有,当按钮处于最底时,点击FAB会将按钮返回到第2个步骤了。
我稍微的对上面那图做些备注,你们就很容易明白为什么是这个动画效果,以及最初那几个问题(300.0f代表什么含义)。
明白了没有,300.0f表示的是相对于控件最初最初位置的一个距离,因为这里是Y轴平移,所以上面那代码的动画效果就是将mView控件从当前位置,沿Y轴平移到距离控件最初位置300的地方。
所以,当我们改动代码后才会有那个效果,因为点击FAB,是将控件平移到距离最初起始位置为200的地方。然后再点击按钮本身时,代码意思是将控件从当前位置平移到距离最初位置300的地方,但此时控件的位置并不是在最初的位置,而是已经经过一次平移,处于距离最初位置200的地方,当前控件要平移到300的地方,只需要再平移100就够了。所以第二次控件下移的距离才会比第一次短。之后的效果就不要我再来讲解了吧,记住300.f和200.0f都是相对于最初位置的距离,然后就可以很好的理解上图的动画了。
花这么多力气说这个,是因为题主觉得,对于初学者来说,要确切的理解参数的含义,这样才可以根据自己想要实现的动画效果来计算需要传递进去的数值是多少。
好了,如果我们现在要实现这样一个动画效果,让控件从当前位置沿Y轴平移到距离最初位置200的地方,那么代码该怎么写?
ValueAnimator animator = ValueAnimator.ofFloat(mView.getTranslationY(),200.0f);
...
现在再来实现,很简单,对吧。那么,再来,如果我们要实现,让控件从当前位置沿Y轴平移200呢?
ValueAnimator animator = ValueAnimator.ofFloat(mView.getTranslationY() , mView.getTranslationY() + 200.0f );
...
怎么样,想对了吗。注意这里的需求是要相对于当前位置移动200,所以数值要怎么计算明白了吧。
理解了参数的含义,想要实现各种动画效果就更有可能了。以上,均为题主学习中碰到的问题和自己的理解,如果有错误的地方,还望告知,不然误导了别人可就不好了。
ObjectAnimator
题主是先接触的ValueAnimator,然后才接触ObjectAnimator的,基本的动画效果用这两个都能实现,而且ObjectAnimator实现起来,比ValueAnimator方便多了,反正题主现在是喜欢用ObjectAnimator就是了。
给你们看下,上面贴出来的代码实现的动画效果,用ObjectAnimator该怎么写:
ObjectAnimator animator = ObjectAnimator.ofFloat(mView,"translationY",mView.getTranslationY(),300.0f);
animator.setDuration(1000);
animator.start();
一句代码就搞定,简单多了。虽然简单,但也有几点需要注意的,数值的确定问题跟上面一样,上面理解了这里就可以直接用了,就不再多说了。
那么,就只剩下第二个参数"translationY"这个问题了。它的作用就是指定要实现的是哪个动画属性,说白点,属性动画就是通过不断修改属性值来达到效果的,这点在上面分析的第二点给出的代码上也可以很容易看出来。
那么,这个属性值到底有哪些,这个字符串的参数可以传递哪些进去?不知道有没有初学者跟题主一样,刚接触时都有这个困惑。
去网上查找,你会发现,很多大神都给列举出了其他一些取值,比如"alpha"、"rotationX/Y"等等,那么这些值是从哪来的呢?可以看一看郭神的这一篇。这里就稍微提一下,如果你突然忘记某个动画单词该怎么拼,或者不知道它支不支持使用这个方法,可以利用AS的查看源码方式到View里面去查找一下setXXX()和getXXX()方法,如果有,则支持。
Github
最后附上Demo源代码地址,有兴趣可以看看,代码很粗糙,只是为了理解怎么用而写的,大家就忽略掉这个问题吧。
AnimatorDemo:https://github.com/woshidasusu/AnimatorDemo
【Android】使用属性动画碰到的困惑及讲解的更多相关文章
- android使用属性动画代替补间动画
本文参考Android属性动画完全解析(上),初识属性动画的基本用法 android3.0之前一共有两种动画,分别是frame动画和tween动画,关于这两种动画如果不了解可以查看我之前的文章andr ...
- 【Android】属性动画
转载请注明出处:http://blog.csdn.net/h28496/44338669 属性动画的原理 通过不断的设置一个View的属性让其出现动画效果.比如,不断地设置一个Button的x值.这个 ...
- Android之属性动画(二)
上一篇文章(链接:http://www.cnblogs.com/jerehedu/p/4458928.html ),我们对属性动画有了简单的认识,并实际动手使用ObjectAnimator.Anim ...
- Android之属性动画(一)
一.概述 Android平台中常用的动画主要有两类,一类是View动画,一类是3.0后新增的属性动画.属性动画与View动画相比功能更加强大,主要体现在以下两个方面: 1. 属性动画不仅仅能应用到V ...
- Android使用属性动画ValueAnimator动态改变SurfaceView的背景颜色
以下是主要代码,难点和疑问点都写在注释中: /** * 开始背景动画(此处为属性动画) */ private void startBackgroundAnimator(){ /* *参数解释: *ta ...
- Android开发属性动画
普通动画效果和属性动画效果区别: 普通动画效果的动画播放后只是产生了视觉欺骗,并没有移动真实的控件. 属性动画直接真实的移动控件 AnimationSet动画: TextView t1 = (Text ...
- Android 用属性动画自定义view的渐变背景
自定义view渐变背景,同时监听手势自动生成小圆球. 宿主Activity如下: package com.edaixi.tempbak; import java.util.ArrayList; imp ...
- Android ViewPager+属性动画 实现炫酷视差动画效果
ViewPager有一个setPageTransform()方法可以实现很多酷炫的动画效果 先来个仿QQ的侧滑面板效果 vp.setPageTransformer(true, new PageTran ...
- Android属性动画源代码解析(超详细)
本文假定你已经对属性动画有了一定的了解,至少使用过属性动画.下面我们就从属性动画最简单的使用开始. ObjectAnimator .ofInt(target,propName,values[]) .s ...
随机推荐
- [.NET领域驱动设计实战系列]专题八:DDD案例:网上书店分布式消息队列和分布式缓存的实现
一.引言 在上一专题中,商家发货和用户确认收货功能引入了消息队列来实现的,引入消息队列的好处可以保证消息的顺序处理,并且具有良好的可扩展性.但是上一专题消息队列是基于内存中队列对象来实现,这样实现有一 ...
- Hadoop Pig简介、安装、试用
相比Java的MapReduce api,Pig为大型数据集的处理提供了更高层次的抽象,与MapReduce相比,Pig提供了更丰富的数据结构,一般都是多值和嵌套的数据结构.Pig还提供了一套更强大的 ...
- php操作xml
最近计划写个人的小网站,一系列原因选择了用php来写,最大的问题就是虽然php很流行,但我从来没有接触过php,看了一个多星期的基本语法后做些小练习热热身,但是期间是各种问题啊,主要是对php不熟悉, ...
- Qt控制台中文乱码问题
本文主要记录了Qt控制台出现中文乱码的问题,一下列出了集中编码设置的方法.以前用VC6.0写的一个贪吃蛇的游戏,今天把源文件拿出来在Qt上面运行,出现中文乱码的问题.以前也遇到过,没想到小小的乱码,折 ...
- Java-继承,多态0922-05
28.按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长.宽两种属性,和计算面积方法. (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长.宽.高属性, 和计算体积的方 ...
- C#学习系列-类与结构的区别
参考:http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=9851&m=9830&ct=31038 如 ...
- iOS----Xcode6或者Xcode7设置LaunchImage图标
最近设置LaunchImage图标时发现怎么都没有效果,后来发现是Xcode6中新建项目的时候会默认添加一个LaunchScreen.xib的文件,我们启动程序的时候也会发现,加载的时LaunchSc ...
- IE和firefox火狐在JS、css兼容区别
1.firefox不能对innerText支持. firefox支持innerHTML但却不支持innerText,它支持textContent来实现innerText,不过默认把多余的空格也保留了. ...
- Topology and Geometry in OpenCascade-Face
Topology and Geometry in OpenCascade-Face eryar@163.com 摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明O ...
- 深入理解PHP内核(六)函数的定义、传参及返回值
一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; } 1.词法分析 在Zend/zend_language_scann ...