补间动画(tweening,就是 in between 的意思)是指填补两个图形之间的变化,让第一个图形 逐渐改变成第二个图形。Android 提供位移、缩放、旋转、透明化等补间动画的功能,而这些功能 可以应用在大部分的 UI 组件上,让开发者可以很简单地将 UI 组件加上动画,使得 UI 界面更加丰 富活泼,并提高使用者与操作界面的互动性。建议在 XML 文件内设置补间动画的各种效果,而不 要直接以程序代码编写。这点其实就与之前所述将界面设置放在 layout 文件内的概念相同, 因为使 用 XML 文件来设置,可以增加可读性与重复利用性。一般而言,会将设置补间动画的 XML 文件 放在 Android 项目的 res/anim 目录内。设置补间动画常用到的 XML 属性大都定义在 Animation 类 内,说明如表 54 所示:
▼ 表 54 Animation 类的 XML 属性
属性名称 说明 属性值
android:duration 动画播放的时间,单位为毫秒。对应的方
法为 setDuration(long)。 整数,不可为负值。
android:interpolator 6
指定动画的运行效果。设置位移补间动画 后,还需要指定整个位移过程的效果是 accelerate(加速)还是 decelerate(减速)。 对应的方法为 setInterpolator(Interpolator)。
l linear_interpolator(线性)
l accelerate_interpolator(加速)
l decelerate_interpolator(减速)
l anticipate_interpolator(先退后进)
l overshoot_interpolator(冲过头)
l bounce_interpolator(反弹)
l cycle_interpolator(以曲线方式加快重复次数) 7 预设为 linear_interpolator
android:repeatCount 动 画 重 复 播 放 次 数 。 对 应 的 方 法 为 setRepeatCount(int)。
整数。1 代表无限重复播放。
预设为 0(不重复播放)。
6 所有的动画特效请参看 R.anim 类的常数。
7 请参考 CycleInterpolator 类说明。
续表 Animation 类的 XML 属性
属性名称 说明 属性值
android:repeatMode 动 画 重 复 播 放 模 式 。 对 应 的 方 法 为 setRepeatMode(int)。
l restart:重新播放。
l reverse:反向播放。
预设为 restart。
android:startOffset
设置主动画开始后多久才运行此动画,单 位为毫秒。要播放多个动画时,可以使用 这个属性来指定各个动画播放的相对时 间。对应的方法为 setStartOffset(long)。
整数,不可为负值。
android:pivotX /android:pivotY 组件的哪个位置会发生补间动画,指 定该位置的 X 轴/ Y 轴坐标 8 。 android:fromXDelta /android:fromYDelta 位移开始时组件的 X 轴/ Y 轴坐标。
android:toXDelta /android:toYDelta 位移结束时组件的 X 轴/ Y 轴坐标。
浮点数。
与缩放有关的 XML 属性 android:fromXScale /android:fromYScale 缩放开始时组件的水平/垂直尺寸。
android:toXScale /android:toYScale 缩放结束时组件的水平/垂直尺寸。
浮点数。
l 1.0 代表维持原来尺寸。
l < 1.0 代表缩小。
l > 1.0 代表放大。
与旋转有关的 XML 属性
android:fromDegrees 旋转开始时组件的角度。
android:toDegrees 旋转结束时组件的角度。
浮点数。
l < 0.0 代表逆时针。
l > 0.0 代表顺时针。
与透明化有关的 XML 属性
android:fromAlpha 动画开始时组件的透明度。
android:toAlpha 动画结束时组件的透明度。
介于 0.0~1.0 之间的浮点数。
l 0.0 代表完全透明。
l 1.0 代表完全不透明。
8 原点 (0,0) 在左上角,向右则 X 轴的值增加;向下则 Y 轴的值增加。
Android 提供许多与补间动画设置有关的 XML 标签以方便开发者快速实现补间动画的功能,
每个卷标都会对应到 Android.view.animation 组件内的类,说明如下 9 :
l <translate>:提供位移补间动画的功能,对应的类为 TranslateAnimation。
l <scale>:提供缩放补间动画的功能,对应的类为 ScaleAnimation。
l <rotate>:提供旋转补间动画的功能,对应的类为 RotateAnimation。
l <alpha>:提供透明化补间动画的功能,对应的类为 AlphaAnimation。
l <set>:使用此标签可以将数个补间动画设置成同一群组而一同播放,而且可以共享相同 的设置,对应的类为 AnimationSet。
使用补间动画所需使用到的方法说明如表 56 所示:
▼ 表 56 AnimationUtils 类 public static Animation loadAnimation (Context context, int id)
加载资源目录内的动画配置文件案。
l context:加载资源文件需给予指定的 Context 对象,一般为 Activity 对象。
l id:动画配置文件对应的资源 ID。
View 类 public void startAnimation (Animation animation)
开始运行指定的动画。
l animation:要播放的 Animation 对象。
范例 TweenAnimEx
图 515
9 TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation、AnimationSet 等类都是 Animation 的子类。
范例说明:
l 按下“振动”按钮,EditText 会左右快速摇晃。
l 单击中间部分的 Spinner,可以选择“一二三四”文字要播放的特效。
l 单击下面部分的 Spinner,可以选择“百战不殆”文字要播放的特效。
TweenAnimEx/res/layout/main.xml
56. <ViewFlipper android:id="@+id/fpText"
57. android:layout_width="match_parent"
58. android:layout_height="wrap_content"
59. android:flipInterval="1500"
60. android:layout_marginTop="10dp"
61. android:layout_marginBottom="10dp" >
62. <TextView
63. android:layout_width="match_parent"
64. android:layout_height="wrap_content"
65. android:gravity="center_horizontal"
66. android:textSize="20sp"
67. android:text="@string/anim_text1"/>
68. <TextView
69. android:layout_width="match_parent"
70. android:layout_height="wrap_content"
71. android:gravity="center_horizontal"
72. android:textSize="20sp"
73. android:text="@string/anim_text2"/>
74. <TextView
75. android:layout_width="match_parent"
76. android:layout_height="wrap_content"
77. android:gravity="center_horizontal"
78. android:textSize="20sp"
79. android:text="@string/anim_text3"/>
80. </ViewFlipper>
56 行:ViewFlipper 是一个简易的动画组件,可以加入多个 View 组件进来。
6279 行共加入 3 个 TextView 组件,不过 1 次仅能显示 1 个。ViewFlipper 可以设置每个子组件显 示出来的间隔时间。
59 行:设置每隔 1500 毫秒显示 1 个子组件。
TweenAnimEx/src/org/tweenAnimEx/TweenAnimEx.java
36. private void findViews_anim01() {
37. etUserName = (EditText)findViewById(R.id.etUserName);
38. btnSubmit = (Button)findViewById(R.id.btnSubmit);
39. btnSubmit.setOnClickListener(new OnClickListener() { 40. @Override
41. public void onClick(View v) {
42. Animation anim = AnimationUtils.loadAnimation(
43. TweenAnimEx.this, R.anim.anim_edittext);
44. etUserName.startAnimation(anim);
45. } 46. });
47. }
4243 行:载入“res/anim/anim_edittext.xml”动画配置文件。
44 行:将 etUserName(EditText 组件)套用并播放 anim 所代表的动画效果。
49. private void findViews_anim02() {
50. tvAnim = (TextView)findViewById(R.id.tvAnim);
51. spInter = (Spinner)findViewById(R.id.spInter);
52. spInter.setOnItemSelectedListener(new OnItemSelectedListener() { 53. @Override
54. public void onItemSelected(AdapterView parent, 55. View view, int pos, long id) {
56. View parentView = (View)tvAnim.getParent();
57. TranslateAnimation anim = new TranslateAnimation(
58. 0.0f,
59. parentView.getWidth() parentView.getPaddingLeft() 60. parentView.getPaddingRight() tvAnim.getWidth(), 61. 0.0f, 0.0f);
62. anim.setDuration(1000);
63. anim.setStartOffset(300);
64. anim.setRepeatMode(Animation.RESTART);
65. anim.setRepeatCount(Animation.INFINITE);
66.
67. int inter_id = android.R.anim.accelerate_interpolator;
68. switch (pos) {
69. case 0:
70. inter_id = android.R.anim.accelerate_interpolator;
71. break;
72. case 1:
73. inter_id = android.R.anim.decelerate_interpolator;
74. break;
75. case 2:
76. inter_id = android.R.anim.accelerate_decelerate_interpolator;
77. break;
78. case 3:
79. inter_id = android.R.anim.anticipate_interpolator;
80. break;
81. case 4:
82. inter_id = android.R.anim.overshoot_interpolator;
83. break;
84. case 5:
85. inter_id = android.R.anim.anticipate_overshoot_interpolator;
86. break;
87. case 6:
88. inter_id = android.R.anim.bounce_interpolator;
89. break;
90. }
91. anim.setInterpolator(AnimationUtils.loadInterpolator(
92. TweenAnimEx.this, inter_id));
93. tvAnim.startAnimation(anim);
94. } 95.
96. @Override
97. public void onNothingSelected(AdapterView parent) {}
98. });
99. }
57 行:TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) 属 于位移补间动画,建构式的 4 个参数分别代表:fromXDelta——位移开始时组件的 X 轴坐标;
toXDelta——位移结束时组件的 X 轴坐标;fromYDelta——位移开始时组件的 Y 轴坐标;toYDelta
——位移结束时组件的 Y 轴坐标。
5861 行:只有第 2 个参数值不是 0.0 代表组件作水平移动,而“parentView.getWidth() parentView.getPaddingLeft() parentView.getPaddingRight() tvAnim.getWidth()”是指“父组件的宽 度 减 父组件左边填充宽度 减 父组件右边填充宽度 减 动画组件宽度” ,剩下的宽度即为位移的 宽度;这代表组件位移时,从 X 轴 0.0 的位置向右移至不会超出父组件的极限,因为不希望动画组 件向右位移时被父组件遮蔽。
62 行:动画持续播放 1000 毫秒。
63 行:主动画开始 300 毫秒后才运行此动画。
64 行:设置重复播放(Animation.RESTART)动画。
65 行:设置无限(Animation.INFINITE)重复播放动画。
6890 行:根据 Spinner 选择的结果决定要采用何种内建的 interpolator 特效。 “android.”开头 代表系统内置。
101. private void findViews_anim03() {
102. fpText = (ViewFlipper)findViewById(R.id.fpText);
103. fpText.startFlipping();
104. spAnim = (Spinner)findViewById(R.id.spAnim);
105. spAnim.setOnItemSelectedListener(new OnItemSelectedListener() { 106. @Override
107. public void onItemSelected(AdapterView parent, 108. View view, int pos, long id) {
109.
110. int anim_in = R.anim.translate_up_in;
111. int anim_out = R.anim.translate_up_out;
112. switch (pos) {
113. case 0:
114. anim_in = R.anim.translate_up_in;
115. anim_out = R.anim.translate_up_out;
116. break;
117. case 1:
118. anim_in = R.anim.translate_left_in;
119. anim_out = R.anim.translate_left_out;
120. break;
121. case 2:
122. anim_in = android.R.anim.fade_in;
123. anim_out = android.R.anim.fade_out;
124. break;
125. case 3:
126. anim_in = R.anim.abstract_in;
127. anim_out = R.anim.abstract_out;
128. break;
129. }
130. fpText.setInAnimation(AnimationUtils.loadAnimation(
131. TweenAnimEx.this, anim_in));
132. fpText.setOutAnimation(AnimationUtils.loadAnimation(
133. TweenAnimEx.this, anim_out));
134. } 135.
136. @Override
137. public void onNothingSelected(AdapterView parent) {}
138. });
139. }
112129 行:根据 Spinner 选择结果决定要采用何种自定义特效配置文件案(放在该项目的
“res/anim”目录内)。