1.5.36 Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition

本文主要是介绍1.5.36 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);}});}

 

默认的布局转换动画

  如果你要使用默认的动画,一个非常简单的方式是在ViewGroupd的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

 

以上转载:http://www.cnblogs.com/mengdd/archive/2013/09/06/3305973.html

这篇关于1.5.36 Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094209

相关文章

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

Java解析JSON的六种方案

《Java解析JSON的六种方案》这篇文章介绍了6种JSON解析方案,包括Jackson、Gson、FastJSON、JsonPath、、手动解析,分别阐述了它们的功能特点、代码示例、高级功能、优缺点... 目录前言1. 使用 Jackson:业界标配功能特点代码示例高级功能优缺点2. 使用 Gson:轻量

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript