Android布局动画之animateLayoutChanges与LayoutTransition

关于布局动画是针对ViewGroup而言的,意指ViewGroup在增加子View或者删除子View时其子View的过渡动画,在Android官网有这么一个简单的例子,其效果如下,接下来我们就通过这个例子来入门


最简单的布局动画实现

事实上,实现上面ViewGroup的布局动画非常简单,我们只要给子View所在的ViewGroup的xml中添加下面的属性即可:
android:animateLayoutChanges="true"
1

1

通过设置以上代码,当ViewGroup在添加View时,子View会呈现出过渡的动画效果,这个动画效果是android默认的显示效果,而且无法使用自定义的动画来替换这个效果,不过还是有其他方式可以实现自定义的过渡动画滴,这个我们后面会分析,下面看看android官方给的demo的代码实现: activity_layout_changes.xml布局文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:showDividers="middle" android:divider="?android:dividerHorizontal" android:animateLayoutChanges="true" android:paddingLeft="16dp" android:paddingRight="16dp" /> </ScrollView> <TextView android:id="@android:id/empty" style="?android:textAppearanceSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="32dp" android:text="@string/message_empty_layout_changes" android:textColor="?android:textColorSecondary" /></FrameLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

布局代码比较简单,使用了一个ScrollView包裹了LinearLayout布局并在LinearLayout中添加了属性android:animateLayoutChanges="true"
,启动了android自带的布局动画,之所以使用ScrollView,是为了在添加子View多时可以进行滑动,而TextView只不过在没有子view时一个提示语。接着看看子View的布局文件list_item_example.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="?android:listPreferredItemHeightSmall" android:orientation="horizontal" android:showDividers="middle" android:divider="?android:dividerVertical" android:dividerPadding="8dp" android:gravity="center"> <TextView android:id="@android:id/text1" style="?android:textAppearanceMedium" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:paddingLeft="?android:listPreferredItemPaddingLeft" /> <ImageButton android:id="@+id/delete_button" android:layout_width="48dp" android:layout_height="match_parent" android:src="@drawable/ic_list_remove" android:background="?android:selectableItemBackground" android:contentDescription="@string/action_remove_item" /></LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

主要控件有用于显示每个子View内容的TextView和用于响应删除子View事件的ImageButton,最后就是Activity的实现: LayoutChangesActivity.Java
package com.example.android.animationsdemo;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.support.v4.app.NavUtils;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/** * This sample demonstrates how to use system-provided, automatic layout transitions. Layout * transitions are animations that occur when views are added to, removed from, or changed within * a {@link ViewGroup}. * * <p>In this sample, the user can add rows to and remove rows from a vertical * {@link android.widget.LinearLayout}.</p> /public class LayoutChangesActivity extends Activity { private ViewGroup mContainerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout_changes); mContainerView = (ViewGroup) findViewById(R.id.container); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); //响应添加事件的menu getMenuInflater().inflate(R.menu.activity_layout_changes, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpTo(this, new Intent(this, MainActivity.class)); return true; case R.id.action_add_item: //添加子View findViewById(android.R.id.empty).setVisibility(View.GONE); addItem(); return true; } return super.onOptionsItemSelected(item); } private void addItem() { //实例化一个子View final ViewGroup newView = (ViewGroup) LayoutInflater.from(this).inflate( R.layout.list_item_example, mContainerView, false); // 随机设置子View的内容 ((TextView) newView.findViewById(android.R.id.text1)).setText( COUNTRIES[(int) (Math.random() * COUNTRIES.length)]); //设置删除按钮的监听 newView.findViewById(R.id.delete_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mContainerView.removeView(newView); // If there are no rows remaining, show the empty view. if (mContainerView.getChildCount() == 0) { findViewById(android.R.id.empty).setVisibility(View.VISIBLE); } } }); //添加子View mContainerView.addView(newView, 0); } /* * A static list of country names. */ private static final String[] COUNTRIES = new String[]{ "Belgium", "France", "Italy", "Germany", "Spain", "Austria", "Russia", "Poland", "Croatia", "Greece", "Ukraine", };}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

代码比较简单,mContainerView作为子View的承载容器,我们可以不断添加子View,也可以移除子View,由于我们在布局文件中启动了android自带的布局动画,所以在添加子View或移除子View都会有过度动画,现在运行程序,效果如下:

这就是android中最简单的布局动画
布局动画实之layoutAnimation

除了上面的布局动画外,有时我们可能需要第一次加载ListView或者GridView的时候能有个动画的过度效果,以便达到更好的体验,如下ListView加载子View的效果:

  事实上实现这种效果也比较简单,我们只需要在ListView的布局文件中添加android:layoutAnimation=”@anim/layout”属性即可。接下来给出实现步骤: 实现动画效果 left_into.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromXDelta="100%" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="0" /> <alpha android:duration="500" android:fromAlpha="0" android:toAlpha="1" /></set>
1
2
3
4
5
6
7
8
9
10
11
12
13

1
2
3
4
5
6
7
8
9
10
11
12
13

这个比较简单,就一个平移和透明度的效果,接着创建layout_animation.xml
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animation="@anim/left_into" android:animationOrder="normal" android:delay="0.5" />
1
2
3
4
5

1
2
3
4
5

这里简单介绍一下layoutAnimation标签属性:
属性名
含义

android:delay
delay的单位为秒,表示子View进入的延长时间

android:animationOrder
子类的进入方式 ,其取值有,normal 0 默认 ,reverse 1 倒序 ,random 2 随机

android:animation
子view要执行的具体动画的文件,自定义即可

然后设置给listView控件即可,activity_listview.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:layoutAnimation="@anim/layout_animation" > </ListView></LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

1
2
3
4
5
6
7
8
9
10
11
12
13
14

ListViewActivity.java代码如下:
package com.example.android.animationsdemo;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by zejian * Time 16/9/17. * Description: */public class ListViewActivity extends Activity { private ListView listView; private List<String> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); listView= (ListView) findViewById(R.id.listView); initData(); listView.setAdapter(new Myadpter()); } public void initData(){ list = new ArrayList<>(); for(int i=1;i<30;i++){ list.add("布局动画listView测试_"+i); } } private class Myadpter extends BaseAdapter{ @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv= new TextView(ListViewActivity.this); tv.setTextSize(20); tv.setHeight(100); tv.setText(list.get(position)); return tv; } }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

执行以上代码,效果就是前面我们给出listView进入的动态效果,这里特别注意的是,动画只在listView子View第一次进入时有效,如果后面动态给listView添加子View时,此动画效果无效,当然除了通过xml设置外,我们还可以通过代码动态设置,代码范例如下,这里就不演示了。
//通过加载XML动画设置文件来创建一个Animation对象,子View进入的动画Animation animation=AnimationUtils.loadAnimation(this, R.anim.left_into);//得到一个LayoutAnimationController对象;LayoutAnimationController lac=new LayoutAnimationController(animation);//设置控件显示的顺序;lac.setOrder(LayoutAnimationController.ORDER_REVERSE);//设置控件显示间隔时间;lac.setDelay(0.5f);//为ListView设置LayoutAnimationController属性;listView.setLayoutAnimation(lac);
1
2
3
4
5
6
7
8
9
10

1
2
3
4
5
6
7
8
9
10

通过AnimationUtils.loadAnimation加载子View的动画来并返回一个Animation对象,然后将Animation对象设置到LayoutAnimationController中并返回LayoutAnimationController对象,配置LayoutAnimationController对象的一些属性,最后设置到ListView中,其中LayoutAnimationController对应layoutAnimation标签,这里需要注意的是layoutAnimation动画不仅仅限于ListView,GridView中,也可用于一切ViewGroup中。
布局动画实之LayoutTransition

前面我们说过ViewGroup在设置android:animateLayoutChanges="true"
后在添加或者删除子view时可以启用系统带着的动画效果,但这种效果无法通过自定义动画去替换。不过还好android官方为我们提供了LayoutTransition类,通过LayoutTransition就可以很容易为ViewGroup在添加或者删除子view设置自定义动画的过渡效果了。   LayoutTransition类用于当前布局容器中需要View添加,删除,隐藏,显示时设置布局容器子View的过渡动画。也就是说利用LayoutTransition,可以分别为需添加或删除的View对象在移动到新的位置的过程添加过渡的动画效果。我们可以通过setLayoutTransition()方法为布局容器ViewGroup设置LayoutTransition对象,代码如下:
//初始化容器动画LayoutTransition mTransitioner = new LayoutTransition();container.setLayoutTransition(mTransitioner);
1
2
3

1
2
3

一般地,Layout中的子View对象有四种动画变化的形式,如下:
属性值
含义

LayoutTransition.APPEARING
子View添加到容器中时的过渡动画效果。

LayoutTransition.CHANGE_APPEARING
子View添加到容器中时,其他子View位置改变的过渡动画

LayoutTransition.DISAPPEARING
子View从容器中移除时的过渡动画效果。

LayoutTransition.CHANGE_DISAPPEARING
子View从容器中移除时,其它子view位置改变的过渡动画

LayoutTransition.CHANGING
子View在容器中位置改变时的过渡动画,不涉及删除或者添加操作

下面给出一个例子,先看布局文件activity_layout_animation.xml
<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:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="addView" android:text="添加控件" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="removeView" android:text="移除控件" /> </LinearLayout> <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /></LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

比较简单不啰嗦,接着看看LayoutAnimationActivity.java
package com.example.android.animationsdemo;import android.animation.LayoutTransition;import android.animation.ObjectAnimator;import android.animation.PropertyValuesHolder;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.LinearLayout;/** * Created by zejian * Time 16/9/17. * Description: /public class LayoutAnimationActivity extends Activity { private int i = 0; private LinearLayout container; private LayoutTransition mTransitioner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout_animation); container = (LinearLayout) findViewById(R.id.container); //构建LayoutTransition mTransitioner = new LayoutTransition(); //设置给ViewGroup容器 container.setLayoutTransition(mTransitioner); setTransition(); } private void setTransition() { /* * 添加View时过渡动画效果 / ObjectAnimator addAnimator = ObjectAnimator.ofFloat(null, "rotationY", 0, 90,0). setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING)); mTransitioner.setAnimator(LayoutTransition.APPEARING, addAnimator); /* * 移除View时过渡动画效果 / ObjectAnimator removeAnimator = ObjectAnimator.ofFloat(null, "rotationX", 0, -90, 0). setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING)); mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, removeAnimator); /* * view 动画改变时,布局中的每个子view动画的时间间隔 / mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30); mTransitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30); /* LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING的过渡动画效果 * 必须使用PropertyValuesHolder所构造的动画才会有效果,不然无效!使用ObjectAnimator是行不通的, * 发现这点时真特么恶心,但没想到更恶心的在后面,在测试效果时发现在构造动画时,”left”、”top”、”bottom”、”right”属性的 * 变动是必须设置的,至少设置两个,不然动画无效,问题是我们即使这些属性不想变动!!!也得设置!!! * 我就问您恶不恶心!,因为这里不想变动,所以设置为(0,0) * / PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 0); PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 0); PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 0); / * view被添加时,其他子View的过渡动画效果 / PropertyValuesHolder animator = PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1); final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder( this, pvhLeft, pvhBottom, animator). setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING)); //设置过渡动画 mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn); /* * view移除时,其他子View的过渡动画 */ PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1); final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder( this, pvhLeft, pvhBottom, pvhRotation). setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING)); mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut); } public void addView(View view) { i++; Button button = new Button(this); button.setText("布局动画_" + i); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); container.addView(button, Math.min(1, container.getChildCount()), params); } public void removeView(View view) { if (i > 0) container.removeViewAt(0); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

简单分析一下,LayoutTransition.APPEARING和LayoutTransition.DISAPPEARING的情况下直接使用属性动画来设置过渡动画效果即可,而对于LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING必须使用PropertyValuesHolder所构造的动画才会有效果,不然无效,真特么恶心, ,但没想到更恶心的在后面,在测试效果时发现在构造动画时,”left”、”top”、”bottom”、”right”属性的变动是必须设置的,至少设置两个,不然动画无效,最坑爹的是我们即使这些属性不想变动!!!也得设置!!!我就问您恶不恶心!,那么我们不想改变这四个属性时该如何设置呢?这时只要传递的可变参数都一样就行如下面的(0,0)也可以是(100,100)即可(坑爹啊!测试半天才发现,一直在考虑代码有没有问题,最后发现时特么的也是醉了…….):
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",0,0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("left",100,100); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("bottom",0,0); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("right",0,0);
1
2
3
4

1
2
3
4

还有点需要注意的是在使用的ofInt,ofFloat中的可变参数值时,第一个值和最后一个值必须相同,不然此属性将不会有动画效果,比如下面首位相同是有效的
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",100,0,100);PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top",0,100,0);
1
2

1
2

但是如果是下面的设置就是无效的:
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("left",0,100);
1

1

关于PropertyValuesHolder,后面我会分开单独一篇来分析,这里我们只需知道PropertyValuesHolder构造的动画可以设置给ObjectAnimator.ofPropertyValuesHolder()便可以产生响应的动画效果即可,该方法原型如下:
public static ObjectAnimator ofPropertyValuesHolder(Object target, PropertyValuesHolder... values)
1

1

最后我们通过setAniamtor的方法设置LayoutTransition的5种状态下的过渡动画,最后运行一下程序,效果如下:

最后这里小结一下LayoutTransition的一些常用函数:
函数名称
说明

setAnimator(int transitionType, Animator animator)
设置不同状态下的动画过渡,transitionType取值为, APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING 、CHANGING

setDuration(long duration)
设置所有动画完成所需要的时长

setDuration(int transitionType, long duration)
设置特定type类型动画时长,transitionType取值为, APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING 、CHANGING

setStagger(int transitionType, long duration)
设置特定type类型动画的每个子item动画的时间间隔 ,transitionType取值为: APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING、CHANGING

setInterpolator(int transitionType, TimeInterpolator interpolator)
设置特定type类型动画的插值器, transitionType取值为: APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING、CHANGING

setStartDelay(int transitionType, long delay)
设置特定type类型动画的动画延时 transitionType取值为, APPEARING、DISAPPEARING、CHANGE_APPEARING、CHANGE_DISAPPEARING 、CHANGING

addTransitionListener(TransitionListener listener)
设置监听器TransitionListener

关于监听器接口TransitionListener原型如下:
/** * This interface is used for listening to starting and ending events for transitions. /public interface TransitionListener { /* * 监听LayoutTransition当前对应的transitionType类型动画开始 * @param transition LayoutTransition对象实例 * @param container LayoutTransition绑定的容器-container * @param view 当前在做动画的View对象 * @param transitionType LayoutTransition类型,取值有:APPEARING、DISAPPEARING、 * CHANGE_APPEARING、CHANGE_DISAPPEARING、CHANGING / public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType); /* * 监听LayoutTransition当前对应的transitionType类型动画结束 * @param transition LayoutTransition对象实例 * @param container LayoutTransition绑定的容器-container * @param view 当前在做动画的View对象 * @param transitionType LayoutTransition类型,取值有:APPEARING、DISAPPEARING、 * CHANGE_APPEARING、CHANGE_DISAPPEARING、CHANGING */ public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

注释比较清晰,就不过多说明,我们如果想在某种transitionType类型动画开或者结束时设置某些操作,便可实现该接口,测试效果也比较简单,这里就不举例了。ok~,关于布局动画就先了解这么多吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,571评论 25 707
  • 之前一篇文章总结了View动画、属性动画、帧动画,这篇文章继续总结布局动画、转场动画。 一、布局动画 布局动画的作...
    xiaoyanger阅读 8,038评论 7 48
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,580评论 0 9
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,868评论 0 10
  • 请告诉我你说话有点委屈感是怎么回事呢? 答,有点不自信,来源思想。 你知道根源吗? 答,知道,我要如何做到对自己的...
    影子陪伴灵魂阅读 268评论 0 0