博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
阅读量:5965 次
发布时间:2019-06-19

本文共 5558 字,大约阅读时间需要 18 分钟。

Property animation系统还提供了对ViewGroup中的View改变加入动画的功能。

  你可以使用  对ViewGroup中的View改变进行动画显示。

  注意,本文所说的动画效果都是设置给容器(ViewGroup),然而效果是通过容器存放的View来体现的。

 

四种容器转换动画类型

  当你添加或者移除ViewGroup中的View时,或者你调用View的方法来控制其显示或消失时,就处于一个转换状态。这种事件就有可能会激发动画。

  当前被增加或者移除的View可以经历一个出现的动画或者一个消失的动画。

  而且不止是当前要控制的View,ViewGroup中的其他View也可以随之进行变动,比如经历一个动画移动到新的位置。

 

  所以一共有四种相关的动画类型

  1.View本身的出现动画;

  2.消失动画;

  3.由于新增了其他View而需要改变位置的动画;

  4.由于移除了其他View而需要改变位置的动画。

  (如果增加或移除了其他View之后,当前View的位置不需要改变,则无动画)。

 

  你可以自定义这些动画,通过 方法把它们设置进一个  对象中去。

  设置的时候需要一个  对象和一个常数:

  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.

 

  你可以自己定义这四种事件类型的动画,也可以使用默认的动画。

  最后通过方法把这些动画以一个  对象的形式设置给一个ViewGroup即可。

  比如下面这个方法就生成了一个全新的LayoutTransition对象并set给容器(ViewGroup类型),这样四个动画就全是默认动画。

 

// 重新生成LayoutTransition对象并设置给container    private void resetTransition() {        mTransitioner = new LayoutTransition();        container.setLayoutTransition(mTransitioner);    }

 

  为这个mTransitioner对象生成四个自定义动画:

 
// 生成自定义动画    private void setupCustomAnimations() {        // 动画:CHANGE_APPEARING        // Changing while Adding        PropertyValuesHolder 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 Removing        Keyframe 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        // Adding        ObjectAnimator 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        // Removing        ObjectAnimator 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:

 
 

  

  

  我把布局改成了线性布局,只要是ViewGroup类型都可以。

 

  默认情况下,DISAPPEARING和CHANGE_APPEARING动画是立即开始的,其他动画都有一个默认的开始延迟。

  这是因为,比如:当一个新的View出现的时候,其他View要立即执行CHANGE_APPEARING动画腾出位置,而新出现的View在一定延迟之后再执行APPEARING出现;

  相反地,一个View消失的时候,它需要先DISAPPEARING动画消失,而其他的View需要先等它消失后再执行CHANGE_DISAPPEARING。

  当然这些默认的行为都可以通过  和等方法改变。

 

API Demos代码

  ApiDemos中布局动画相关的类有:LayoutAnimationsByDefault 、LayoutAnimations、LayoutAnimationsHideShow。

  完整的项目可以去github下载。

 

参考资料

  API Guides: Property Animation

  

  其中的Animating Layout Changes to ViewGroups

  LayoutTransition类Reference:

  

  项目地址:

  

转载地址:http://ravax.baihongyu.com/

你可能感兴趣的文章
程序员全国不同地区,微信(面试 招聘)群。
查看>>
【干货】界面控件DevExtreme视频教程大汇总!
查看>>
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
深入理解Java的接口和抽象类
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>