Animation动画详解(十二)--animateLayoutChanges与LayoutTransition_html/css_WEB-ITnose
前言:生活不只眼前的苟且,还有诗和远方的田野
相关文章:
1、《Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法》
2、《Animation动画详解(二)——Interpolator插值器》
3、《Animation动画详解(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画》
4、《Animation动画详解(四)——ValueAnimator基本使用》
5、《Animation动画详解(五)——ValueAnimator高级进阶(一)》
6、《Animation动画详解(六)——ValueAnimator高级进阶(二)》
7、《Animation动画详解(七)——ObjectAnimator基本使用》
8、《 Animation动画详解(八)——PropertyValuesHolder与Keyframe》
9、《 Animation动画详解(九)——联合动画的代码实现》
10、《Animation动画详解(十)——联合动画的XML实现与使用示例》
11、《 Animation动画详解(十一)——layoutAnimation与gridLayoutAnimation》
12、《Animation动画详解(十二)——animateLayoutChanges与LayoutTransition》
前篇给大家讲了LayoutAnimation的知识,LayoutAnimation虽能实现ViewGroup的进入动画,但只能在创建时有效。在创建后,再往里添加控件就不会再有动画。在API 11后,又添加了两个能实现在创建后添加控件仍能应用动画的方法,分别是android:animateLayoutChanges属性和LayoutTransition类。这篇文章就来简单说一下他们的用法。由于他们的API 等级必须>=11,API等级稍高,且存在较多问题,并不建议读者使用,本篇只讲解具体用法,不做深究.
一、android:animateLayoutChanges属性
在API 11之后,Android为了支持ViewGroup类控件,在添加和移除其中控件时自动添加动画,为我们提供了一个非常简单的属性:android:animateLayoutChanges=[true/false],所有派生自ViewGroup的控件都具有此属性,只要在XML中添加上这个属性,就能实现添加/删除其中控件时,带有默认动画了。我们来看下这次的效果图:
然后来看看具体代码是如何来做的:
1、main.xml布局代码
<?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"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <button android:id="@+id/add_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加控件"></button> <button android:id="@+id/remove_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="移除控件"></button> </linearlayout> <linearlayout android:id="@+id/layoutTransitionGroup" android:layout_width="match_parent" android:layout_height="wrap_content" android:animatelayoutchanges="true" android:orientation="vertical"></linearlayout></linearlayout>
2、MyActivity代码
MyActivity的代码也很简单,就是在点击添加按钮时向其中动态添加一个btn,在点击删除按钮时,将其中第一个按钮给删除。public class MyActivity extends Activity implements View.OnClickListener { private LinearLayout layoutTransitionGroup; private int i = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup); findViewById(R.id.add_btn).setOnClickListener(this); findViewById(R.id.remove_btn).setOnClickListener(this); } private void addButtonView() { i++; Button button = new Button(this); button.setText("button" + i); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); button.setLayoutParams(params); layoutTransitionGroup.addView(button, 0); } private void removeButtonView() { if (i > 0) { layoutTransitionGroup.removeViewAt(0); } i--; } @Override public void onClick(View v) { if (v.getId() == R.id.add_btn) { addButtonView(); } if (v.getId() == R.id.remove_btn) { removeButtonView(); } }}
由上面的效果图可见,我们只需要在viewGroup的XML中添加一行代码android:animateLayoutChanges=[true]即可实现内部控件添加删除时都加上动画效果。
下面我们来做下对比,如果把上面LinearLayout中的android:animateLayoutChanges=[true]给去掉的效果是怎样的?大家来看下原始添加控件是怎样的,就知道默认动画效果是什么了。
在没加android:animateLayoutChanges=true时:
可见,在添加和删除控件时是没有任何动画的。经过对比就可知道,默认的进入动画就是向下部控件下移,然后新添控件透明度从0到1显示出来。默认的退出动画是控件透明度从1变到0消失,下部控件上移。
源码在文章底部给出
二、LayoutTransaction
1、概述
上面虽然在ViewGroup类控件XML中仅添加一行android:animateLayoutChanges=[true]即可实现内部控件添加删除时都加上动画效果。但却只能使用默认动画效果,而无法自定义动画。为了能让我们自定义动画,谷歌在API 11时,同时为我们引入了一个类LayoutTransaction。
要使用LayoutTransaction是非常容易的,只需要三步:
第一步:创建实例
LayoutTransaction transitioner = new LayoutTransition();
ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);transitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);
linearLayout.setLayoutTransition(mTransitioner);
public void setLayoutTransition(LayoutTransition transition)
public void setAnimator(int transitionType, Animator animator)
第一个参数 int transitionType:表示当前应用动画的对象范围,取值有:
第二个参数 Animator animator:表示当前所选范围的控件所使用的动画。
2、LayoutTransition.APPEARING与LayoutTransition.DISAPPEARING示例
我们先来看看LayoutTransition.APPEARING与LayoutTransition.DISAPPEARING分别代表什么意义:我们先来看效果图:
大家可以看到,在新增一个btn时,这个新增的btn会有一个绕Y轴旋转360度的动画。这个就是LayoutTransition.APPEARING所对应的当一个控件出现时所对应的动画。
当我们从容器中移除一个控件时,这个被移除的控件会绕Z轴旋转90度后,再消失。这个就是LayoutTransition.DISAPPEARING在一个控件被移除时,此被移除的控件所对应的动画。
这样大家就理解了,LayoutTransition.APPEARING和LayoutTransition.DISAPPEARING的意义。下面我们就来看看代码吧。
这个示例也是建立在上个android:animateLayoutChanges属性所对应示例的基础上的,所以框架部分是一样的,仅列出代码,不再多讲,只讲关键部分
首先是main.xml布局
<?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"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <button android:id="@+id/add_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加控件"></button> <button android:id="@+id/remove_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="移除控件"></button> </linearlayout> <linearlayout android:id="@+id/layoutTransitionGroup" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"></linearlayout></linearlayout>
然后是在MyActivity中的代码处理
public class MyActivity extends Activity implements View.OnClickListener{ private LinearLayout layoutTransitionGroup; private LayoutTransition mTransitioner; private int i = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup); findViewById(R.id.add_btn).setOnClickListener(this); findViewById(R.id.remove_btn).setOnClickListener(this); mTransitioner = new LayoutTransition(); //入场动画:view在这个容器中消失时触发的动画 ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f); mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn); //出场动画:view显示时的动画 ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f); mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut); layoutTransitionGroup.setLayoutTransition(mTransitioner); } private void addButtonView() { i++; Button button = new Button(this); button.setText("button" + i); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); button.setLayoutParams(params); layoutTransitionGroup.addView(button, 0); } private void removeButtonView() { if (i > 0) { layoutTransitionGroup.removeViewAt(0); } i--; } @Override public void onClick(View v) { if (v.getId() == R.id.add_btn) { addButtonView(); } if (v.getId() == R.id.remove_btn) { removeButtonView(); } }}
但是非常注意的是我们的LayoutTransition是在OnCreate中设置的,也就是说是在LinearLayout创建时就给它定义好控件的入场动画和出场动画的,定义代码如下:
mTransitioner = new LayoutTransition();//入场动画:view在这个容器中消失时触发的动画ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f);mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);//出场动画:view显示时的动画ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);layoutTransitionGroup.setLayoutTransition(mTransitioner);
第一步,定义LayoutTransition实例:
mTransitioner = new LayoutTransition();
//入场动画:view在这个容器中消失时触发的动画ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f);mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);//出场动画:view显示时的动画ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);
ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f);mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);
ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);
layoutTransitionGroup.setLayoutTransition(mTransitioner);
3、LayoutTransition.CHANGE_APPEARING与LayoutTransition.CHANGE_DISAPPEARING
我们先来看下本例的效果图,先理解LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING分别是什么意义在这个效果图中,在添加控件时,除了被添加控件本身的入场动画以外,其它需要移动位置的控件,在移动位置时,也被添加上了动画(left点位移动画),这些除了被添加控件以外的其它需要移动位置的控件组合,所对应的动画就是LayoutTransition.CHANGE_APPEARING
同样,在移除一个控件时,因为移除了一个控件,而其它所有需要改变位置的控件组合所对应的动画就是LayoutTransition.CHANGE_DISAPPEARING,这里LayoutTransition.CHANGE_DISAPPEARING所对应的动画是
《 Animation动画详解(八)——PropertyValuesHolder与Keyframe》的响铃效果。
(1)、LayoutTransition.CHANGE_APPEARING实现
我们这里先看看LayoutTransition.CHANGE_APPEARING所对应的完整代码public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup); findViewById(R.id.add_btn).setOnClickListener(this); findViewById(R.id.remove_btn).setOnClickListener(this); mTransitioner = new LayoutTransition(); //入场动画:view在这个容器中消失时触发的动画 ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f); mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn); //出场动画:view显示时的动画 ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f); mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut); PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",1,1); Animator changeAppearAnimator = ObjectAnimator.ofPropertyValuesHolder(layoutTransitionGroup, pvhLeft,pvhBottom,pvhTop,pvhRight); mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING,changeAppearAnimator); layoutTransitionGroup.setLayoutTransition(mTransitioner);}
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0);PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",1,1);Animator changeAppearAnimator = ObjectAnimator.ofPropertyValuesHolder(layoutTransitionGroup, pvhLeft,pvhBottom,pvhTop,pvhRight);mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING,changeAppearAnimator);
1、LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING必须使用PropertyValuesHolder所构造的动画才会有效果,不然无效!也就是说使用ObjectAnimator构造的动画,在这里是不会有效果的!
2、在构造PropertyValuesHolder动画时,”left”、”top”属性的变动是必写的。如果不需要变动,则直接写为:
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,0);PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",0,0);
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0);
4、在构造PropertyValuesHolder时,所使用的ofInt,ofFloat中,如果所有参数值都相同,也将不会有动画效果。
比如:
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",100,100);
看到了吧,坑就是如此多,至于这些都是为什么,我也懒得去研究它的源码,因为LayoutTransition的问题实在是太!多!了!至于这篇文章嘛,由于这是一个Android 动画的系列,而LayoutTransition也是其中一员,本着尊重知识的原则,还是给大家讲一讲,至于应用嘛!呵呵,慎用之……
我们上面讲了,left,top属性是必须的,下面我们给他扩展一下,除了给它添加left,top属性以外,再给它加上scale属性,让它同时放大,代码即:
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0);PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",1,1);PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("ScaleX",1f,9f,1f);Animator changeAppearAnimator = ObjectAnimator.ofPropertyValuesHolder(layoutTransitionGroup, pvhLeft,pvhTop,pvhScaleX);mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING,changeAppearAnimator);
(2)、LayoutTransition.CHANGE_DISAPPEARING实现
好了,我们下面来看看LayoutTransition.CHANGE_DISAPPEARING的具体实现PropertyValuesHolder outLeft = PropertyValuesHolder.ofInt("left",0,0);PropertyValuesHolder outTop = PropertyValuesHolder.ofInt("top",0,0);Keyframe frame0 = Keyframe.ofFloat(0f, 0);Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);Keyframe frame10 = Keyframe.ofFloat(1, 0);PropertyValuesHolder mPropertyValuesHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10);ObjectAnimator mObjectAnimatorChangeDisAppearing = ObjectAnimator.ofPropertyValuesHolder(this, outLeft,outTop,mPropertyValuesHolder);mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mObjectAnimatorChangeDisAppearing);
PropertyValuesHolder outLeft = PropertyValuesHolder.ofInt("left",0,0);PropertyValuesHolder outTop = PropertyValuesHolder.ofInt("top",0,0);
Keyframe frame0 = Keyframe.ofFloat(0f, 0);Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);Keyframe frame10 = Keyframe.ofFloat(1, 0);PropertyValuesHolder mPropertyValuesHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10);
最后一步,设置LayoutTransition.CHANGE_DISAPPEARING动画
ObjectAnimator mObjectAnimatorChangeDisAppearing = ObjectAnimator.ofPropertyValuesHolder(this, outLeft,outTop,mPropertyValuesHolder);mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mObjectAnimatorChangeDisAppearing);
对应效果为:
所以所有动画所对应的完整代码如下:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup); findViewById(R.id.add_btn).setOnClickListener(this); findViewById(R.id.remove_btn).setOnClickListener(this); mTransitioner = new LayoutTransition(); //入场动画:view在这个容器中消失时触发的动画 ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f); mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn); //出场动画:view显示时的动画 ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f); mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut); /** * LayoutTransition.CHANGE_APPEARING动画 */ PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",1,1); //必须第一个值与最后一值相同才会有效果,不然没有效果 PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("ScaleX",1f,9f,1f); Animator changeAppearAnimator = ObjectAnimator.ofPropertyValuesHolder(layoutTransitionGroup, pvhLeft,pvhTop,pvhScaleX); mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING,changeAppearAnimator); /** * LayoutTransition.CHANGE_DISAPPEARING动画 */ PropertyValuesHolder outLeft = PropertyValuesHolder.ofInt("left",0,0); PropertyValuesHolder outTop = PropertyValuesHolder.ofInt("top",0,0); Keyframe frame0 = Keyframe.ofFloat(0f, 0); Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f); Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f); Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f); Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f); Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f); Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f); Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f); Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f); Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f); Keyframe frame10 = Keyframe.ofFloat(1, 0); PropertyValuesHolder mPropertyValuesHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10); ObjectAnimator mObjectAnimatorChangeDisAppearing = ObjectAnimator.ofPropertyValuesHolder(this, outLeft,outTop,mPropertyValuesHolder); mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mObjectAnimatorChangeDisAppearing); layoutTransitionGroup.setLayoutTransition(mTransitioner);}
源码在文章底部给出
4、其它函数
(1)、基本设置
上面我们讲了LayoutTransition的setAnimator方法,在LayoutTransition中还有一些其它方法,下面我们来讲解下:/** * 设置所有动画完成所需要的时长 */public void setDuration(long duration)/** * 针对单个type,设置动画时长; * transitionType取值为:APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING */public void setDuration(int transitionType, long duration) /** * 针对单个type设置插值器 * transitionType取值为:APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING */public void setInterpolator(int transitionType, TimeInterpolator interpolator)/** * 针对单个type设置动画延时 * transitionType取值为:APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING */public void setStartDelay(int transitionType, long delay)/** * 针对单个type设置,每个子item动画的时间间隔 */public void setStagger(int transitionType, long duration)
我们还回来看看上面的效果图:
在这个效果图中,当插入一个控件时,CHANGE_APPEARING动画时的所有控件是一起做动画的,我们需要做动画的控件,逐个做动画,而不是一起全部来做动画,setStagger就是用来设置单个item间的动画间隔的。
在上面的基础上,我们给LayoutTransition.CHANGE_APPEARING添加上每个item间的时间间隔30ms:
mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
明显可以看出,做LayoutTransition.CHANGE_APPEARING的控件确实是有间隔的;
完整代码为:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup); findViewById(R.id.add_btn).setOnClickListener(this); findViewById(R.id.remove_btn).setOnClickListener(this); mTransitioner = new LayoutTransition(); //入场动画:view在这个容器中消失时触发的动画 ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f); mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn); //出场动画:view显示时的动画 ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f); mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut); /** * LayoutTransition.CHANGE_APPEARING动画 */ PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left",0,100,0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",1,1); //必须第一个值与最后一值相同才会有效果,不然没有效果 PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("ScaleX",1f,9f,1f); Animator changeAppearAnimator = ObjectAnimator.ofPropertyValuesHolder(layoutTransitionGroup, pvhLeft,pvhTop,pvhScaleX); mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING,changeAppearAnimator); /** * LayoutTransition.CHANGE_DISAPPEARING动画 */ PropertyValuesHolder outLeft = PropertyValuesHolder.ofInt("left",0,0); PropertyValuesHolder outTop = PropertyValuesHolder.ofInt("top",0,0); Keyframe frame0 = Keyframe.ofFloat(0f, 0); Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f); Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f); Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f); Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f); Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f); Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f); Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f); Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f); Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f); Keyframe frame10 = Keyframe.ofFloat(1, 0); PropertyValuesHolder mPropertyValuesHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10); ObjectAnimator mObjectAnimatorChangeDisAppearing = ObjectAnimator.ofPropertyValuesHolder(this, outLeft,outTop,mPropertyValuesHolder); mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mObjectAnimatorChangeDisAppearing); //设置单个item间的动画间隔 mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30); layoutTransitionGroup.setLayoutTransition(mTransitioner);}
(2)、LayoutTransition设置监听
LayoutTransition还给提供了一个监听函数:public void addTransitionListener(TransitionListener listener)//其中:public interface TransitionListener { public void startTransition(LayoutTransition transition, ViewGroup container,View view, int transitionType); public void endTransition(LayoutTransition transition, ViewGroup container,View view, int transitionType);}
在TransitionListener中总共有四个参数:
mTransitioner.addTransitionListener(new LayoutTransition.TransitionListener() { @Override public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) { Log.d("qijian","start:"+"transitionType:"+transitionType +"count:"+container.getChildCount() + "view:"+view.getClass().getName()); } @Override public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) { Log.d("qijian","end:"+"transitionType:"+transitionType +"count:"+container.getChildCount() + "view:"+view.getClass().getName()); }});
对应的Log输出为:
先看添加第一个控件时:
在startTransition中,除去transitionType:2的APPEARING所对应的动画以外,在transitionType:0所对应的CHANGE_APPEARING时竟然也传给了LinearLayout控件!
同样,在插入第二个控件时,CHANGE_APPEARING事件也进行了上传和监听!
同样在删除控件时,CHANGE_DISAPPEARING也是会上传给父控件的
所对应的Log如下:
所以这里的结论就是:在使用addTransitionListener监听LayoutTransition过程监听时,CHANGE_APPEARING和CHANGE_DISAPPEARING事件都会上传给父类控件!
源码在文章底部给出
到这里,这个系列的知识基本就讲完了,下一篇就是给大家讲讲第三方库nieOldAndroid的用法,做为Android animation动画系列的结尾。源码内容:
1、《BlogAnimateLayoutChanges》:第一部分AnimateLayoutChanges属性所对应的代码
2、《BlogLayoutTransition》:第二部分LayoutTransition所对应的代码
如果本文有帮到你,记得加关注哦
源码下载地址:http://download.csdn.net/download/harvic880925/9473049
请大家尊重原创者版权,转载请标明出处:

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

WebDevelopmentReliesonHtml, CSS 및 JavaScript : 1) HtmlStructuresContent, 2) CSSSTYLESIT, 및 3) JAVASCRIPTADDSINGINTERACTIVITY, BASISOFMODERNWEBEXPERIENCES를 형성합니다.

웹 주석 기능에 대한 Y 축 위치 적응 알고리즘이 기사는 Word 문서와 유사한 주석 기능을 구현하는 방법, 특히 주석 간격을 다루는 방법을 모색합니다 ...

GiteEpages 정적 웹 사이트 배포 실패 : 404 오류 문제 해결 및 해결시 Gitee ...

HTML, CSS 및 JavaScript는 웹 개발의 세 가지 기둥입니다. 1. HTML은 웹 페이지 구조를 정의하고 등과 같은 태그를 사용합니다. 2. CSS는 색상, 글꼴 크기 등과 같은 선택기 및 속성을 사용하여 웹 페이지 스타일을 제어합니다.

이미지를 클릭 한 후 주변 이미지를 산란 및 확대하는 효과를 얻으려면 많은 웹 디자인이 대화식 효과를 달성해야합니다. 특정 이미지를 클릭하여 주변을 만들 수 있습니다 ...
