Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Property animation系统还提供了对ViewGroup中的View改变加入动画的功能。
你可以使用 LayoutTransition
对ViewGroup中的View改变进行动画显示。
注意,本文所说的动画效果都是设置给容器(ViewGroup),然而效果是通过容器存放的View来体现的。
四种容器转换动画类型
当你添加或者移除ViewGroup中的View时,或者你调用View的setVisibility()方法来控制其显示或消失时,就处于一个转换状态。这种事件就有可能会激发动画。
当前被增加或者移除的View可以经历一个出现的动画或者一个消失的动画。
而且不止是当前要控制的View,ViewGroup中的其他View也可以随之进行变动,比如经历一个动画移动到新的位置。
所以一共有四种相关的动画类型:
1.View本身的出现动画;
2.消失动画;
3.由于新增了其他View而需要改变位置的动画;
4.由于移除了其他View而需要改变位置的动画。
(如果增加或移除了其他View之后,当前View的位置不需要改变,则无动画)。
你可以自定义这些动画,通过setAnimator() 方法把它们设置进一个 LayoutTransition
对象中去。
设置的时候需要一个 Animator 对象和一个常数:
APPEARING - A flag indicating the animation that runs on items that are appearing in the container.
CHANGE_APPEARING - A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.
DISAPPEARING - A flag indicating the animation that runs on items that are disappearing from the container.
CHANGE_DISAPPEARING - A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.
你可以自己定义这四种事件类型的动画,也可以使用默认的动画。
最后通过setLayoutTransition(LayoutTransition)
方法把这些动画以一个 LayoutTransition
对象的形式设置给一个ViewGroup即可。
比如下面这个方法就生成了一个全新的LayoutTransition对象并set给容器(ViewGroup类型),这样四个动画就全是默认动画。
// 重新生成LayoutTransition对象并设置给containerprivate void resetTransition() {mTransitioner = new LayoutTransition();container.setLayoutTransition(mTransitioner);}
为这个mTransitioner对象生成四个自定义动画:
// 生成自定义动画private void setupCustomAnimations() {// 动画:CHANGE_APPEARING// Changing while AddingPropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0,1);PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom",0, 1);PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX",1f, 0f, 1f);PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY",1f, 0f, 1f);final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX,pvhScaleY).setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING));mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);changeIn.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator anim) {View view = (View) ((ObjectAnimator) anim).getTarget();view.setScaleX(1f);view.setScaleY(1f);}});// 动画:CHANGE_DISAPPEARING// Changing while RemovingKeyframe kf0 = Keyframe.ofFloat(0f, 0f);Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);Keyframe kf2 = Keyframe.ofFloat(1f, 0f);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight,pvhBottom, pvhRotation).setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING));mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,changeOut);changeOut.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator anim) {View view = (View) ((ObjectAnimator) anim).getTarget();view.setRotation(0f);}});// 动画:APPEARING// AddingObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f,0f).setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);animIn.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator anim) {View view = (View) ((ObjectAnimator) anim).getTarget();view.setRotationY(0f);}});// 动画:DISAPPEARING// RemovingObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotationX", 0f,90f).setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);animOut.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator anim) {View view = (View) ((ObjectAnimator) anim).getTarget();view.setRotationX(0f);}});}
默认的布局转换动画
如果你要使用默认的动画,一个非常简单的方式是在ViewGroup的XML布局文件中把android:animateLayoutchanges
属性设置为true。
这样就自动地按照默认方式来对要移除或添加的View,还有Group中的其他View进行动画。
比如ApiDemos中的LayoutAnimationsByDefault:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><Buttonandroid:id="@+id/addNewButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Add Button" /><!--<GridLayoutandroid:columnCount="4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/gridContainer"android:animateLayoutChanges="true"/>--><LinearLayoutandroid:id="@+id/gridContainer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:animateLayoutChanges="true" android:orientation="vertical"></LinearLayout></LinearLayout>
我把布局改成了线性布局,只要是ViewGroup类型都可以。
默认情况下,DISAPPEARING和CHANGE_APPEARING动画是立即开始的,其他动画都有一个默认的开始延迟。
这是因为,比如:当一个新的View出现的时候,其他View要立即执行CHANGE_APPEARING动画腾出位置,而新出现的View在一定延迟之后再执行APPEARING出现;
相反地,一个View消失的时候,它需要先DISAPPEARING动画消失,而其他的View需要先等它消失后再执行CHANGE_DISAPPEARING。
当然这些默认的行为都可以通过 setDuration(int, long)
和setStartDelay(int, long)
等方法改变。
API Demos代码
ApiDemos中布局动画相关的类有:LayoutAnimationsByDefault 、LayoutAnimations、LayoutAnimationsHideShow。
完整的项目可以去github下载。https://github.com/mengdd/AnimationApiDemos
参考资料
API Guides: Property Animation
http://developer.android.com/guide/topics/graphics/prop-animation.html
其中的Animating Layout Changes to ViewGroups
LayoutTransition类Reference:
http://developer.android.com/reference/android/animation/LayoutTransition.html
项目地址:
https://github.com/mengdd/AnimationApiDemos
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition相关推荐
- Android Animation学习(三) ApiDemos解析:XML动画文件的使用
Android Animation学习(三) ApiDemos解析:XML动画文件的使用 可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <o ...
- Android Animation学习(四) ApiDemos解析:多属性动画
Android Animation学习(四) ApiDemos解析:多属性动画 如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可 ...
- Android Animation学习(六) View Animation介绍
Android Animation学习(六) View Animation介绍 View Animation View animation系统可以用来执行View上的Tween animation和F ...
- Android Animation学习(一) Property Animation原理介绍和API简介
Android Animation学习(一) Property Animation介绍 Android Animation Android framework提供了两种动画系统: property a ...
- android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理)
android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理) Android webrtc摄像头流程分析 1.打开摄像头 2.获取流数据 摄像头切换 问题场景:在使用华为手机(忘 ...
- android animation学习
本文出自http://wangstar.javaeye.com/blog/409115,感觉基础知识归纳得不错,就COPY下来方便查找. 动画效果编程基础--Android Animation ...
- Android JNI学习(五)——Java与Native之间如何实现相互调用
本章将讲述Java与Native之间如何实现相互调用.我将围绕围绕如下三点来讲解. #mermaid-svg-qeVnGlVrLWrB5ryX .label{font-family:'trebuche ...
- Android开发学习之Xml解析归纳
在程序开发中,有两种语言是和平台无关的,它们就是Xml和Json,因此,作为在不同平台间传递信息的Xml和Json在Android中同样扮演者重要的角色,那么今天我们就来一起学习Android中Xml ...
- Android多媒体学习五:调用Android自带的播放器播放Audio
Android有其自带的播放器,我们可以使用隐式Intent来调用它:通过传入一个Action为ACTION_VIEW同时,指定Data为所要播放的Audio的Uri对象,并指定格式信息,则我们就可以 ...
最新文章
- Zabbix(六):项目实战之--自动发现nginx调度器及后端web服务集群、自定义参数监控...
- LinearPolar函数
- php7.0 java 性能,php7代码性能常见优化技巧
- hadoop中如何控制map的数量
- 工作流实战_21_flowable 加签 任务向前加签 向后加签
- 仿微信选取图片发表朋友圈功能
- 尴尬!微软的 PowerShell 竟是 Linux 用户最多!| 极客头条
- Johnson 算法
- 用友凭证打印没有辅助项
- HTML实现页面跳转
- 详解几个基本概念“标准差标准误差,方差均方差”
- 为什么在不同网站查询本机的公网IP不一样?
- Error response from daemon: Pool overlaps with other one on this address space
- html超链接地址隐藏,如何在Excel中隐藏超链接地址?
- canvas雨滴绘制总结(三)
- -XX:CMSInitiatingOccupancyFraction
- Linux IPC:匿名管道 与 命名管道
- vc mfc Edit SetFocus 设置焦点 无效 失败
- Springboot毕设项目坤坤网上商城0573k(java+VUE+Mybatis+Maven+Mysql)
- 新年快乐|202112-月度总结
热门文章
- 小学生计算机课堂实践的重要性,多媒体在小学教学中的重要性
- php邮箱文件发送源码,php简单实现发送带附件的邮件
- mysql和java区别_java和mysql的length()区别及char_length()
- php400错误的请求,Wordpress中的Ajax返回400错误请求,但不确定如何进一步调试 - WordPress - srcmini...
- Centos7 使用Docker安装tomcat
- kubernetes资源对象之security context
- 【ZooKeeper】集群安装与配置
- android:layout_gravity和android:gravity属性的区别
- python%20语言 20培训_Python语言学习之20个值得学习的Python技巧
- 网络天才网页中文版_LVMH 旗下奢侈品电商 24S 的中文版正式上线,还有带来“双 11”优惠...