# 8.4.2 Android动画合集之补间动画
## 本节引言:
> 本节带来的是Android三种动画中的第二种——补间动画(Tween),和前面学的帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定**动画开始**,以及**动画结束**"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!好了,开始本节学习~
## 1.补间动画的分类和Interpolator
Andoird所支持的补间动画效果有如下这五种,或者说四种吧,第五种是前面几种的组合而已~
> * **AlphaAnimation:**透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续 时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应<**alpha**/>标签!
> * **ScaleAnimation**:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点, 还有动画的持续时间;对应<**scale**/>标签!
> * **TranslateAnimation**:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续 时间即可;对应<**translate**/>标签!
> * **RotateAnimation**:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画 持续时间和旋转的轴心;对应<**rotate**/>标签
> * **AnimationSet**:组合渐变,就是前面多种渐变的组合,对应<**set**/>标签
在开始讲解各种动画的用法之前,我们先要来讲解一个东西:**Interpolator**
> 用来控制动画的变化速度,可以理解成动画渲染器,当然我们也可以自己实现Interpolator 接口,自行来控制动画的变化速度,而Android中已经为我们提供了五个可供选择的实现类:
>
> * **LinearInterpolator**:动画以均匀的速度改变
> * **AccelerateInterpolator**:在动画开始的地方改变速度较慢,然后开始加速
> * **AccelerateDecelerateInterpolator**:在动画开始、结束的地方改变速度较慢,中间时加速
> * **CycleInterpolator**:动画循环播放特定次数,变化速度按正弦曲线改变: Math.sin(2 * mCycles * Math.PI * input)
> * **DecelerateInterpolator**:在动画开始的地方改变速度较快,然后开始减速
> * **AnticipateInterpolator**:反向,先向相反方向改变一段再加速播放
> * **AnticipateOvershootInterpolator**:开始的时候向后然后向前甩一定值后返回最后的值
> * **BounceInterpolator**: 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
> * **OvershottInterpolator**:回弹,最后超出目的值然后缓慢改变到目的值
>
> 而这个东东,我们一般是在写动画xml文件时会用到,属性是:**android:interpolator**, 而上面对应的值是:**@android:anim/linear_interpolator**,其实就是驼峰命名法变下划线而已 AccelerateDecelerateInterpolator对应:@android:anim/accelerate_decelerate_interpolator!
## 2.各种动画的详细讲解
这里的**android:duration**都是动画的持续时间,单位是毫秒~
### **1)AlphaAnimation(透明度渐变)**
**anim_alpha.xml**:
```
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="2000"/>
```
属性解释:
**fromAlpha** :起始透明度
**toAlpha**:结束透明度
透明度的范围为:0-1,完全透明-完全不透明
### **2)ScaleAnimation(缩放渐变)**
**anim_scale.xml**:
```
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXScale="0.2"
android:toXScale="1.5"
android:fromYScale="0.2"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
```
属性解释:
> * **fromXScale**/**fromYScale**:沿着X轴/Y轴缩放的起始比例
> * **toXScale**/**toYScale**:沿着X轴/Y轴缩放的结束比例
> * **pivotX**/**pivotY**:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点
### **3)TranslateAnimation(位移渐变)**
**anim_translate.xml**:
```
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXDelta="0"
android:toXDelta="320"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="2000"/>
```
属性解释:
> * **fromXDelta**/**fromYDelta**:动画起始位置的X/Y坐标
> * **toXDelta**/**toYDelta**:动画结束位置的X/Y坐标
### **4)RotateAnimation(旋转渐变)**
**anim_rotate.xml**:
```
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"/>
```
属性解释:
> * **fromDegrees**/**toDegrees**:旋转的起始/结束角度
> * **repeatCount**:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
> * **repeatMode**:设置重复模式,默认**restart**,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成**reverse**,表示偶数次显示动画时会做方向相反的运动!
### **5)AnimationSet(组合渐变)**
非常简单,就是前面几个动画组合到一起而已~
**anim_set.xml**:
```
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:shareInterpolator="true" >
<scale
android:duration="2000"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.5"
android:toYScale="1.5" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:toDegrees="360" />
<translate
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="320"
android:toYDelta="0" />
<alpha
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
```
## 3.写个例子来体验下
好的,下面我们就用上面写的动画来写一个例子,让我们体会体会何为补间动画: 首先来个简单的布局:**activity_main.xml**:
```
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_alpha"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="透明度渐变" />
<Button
android:id="@+id/btn_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="缩放渐变" />
<Button
android:id="@+id/btn_tran"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="位移渐变" />
<Button
android:id="@+id/btn_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="旋转渐变" />
<Button
android:id="@+id/btn_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="组合渐变" />
<ImageView
android:id="@+id/img_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="48dp"
android:src="@mipmap/img_face" />
</LinearLayout>
```
好哒,接着到我们的**MainActivity.java**,同样非常简单,只需调用AnimationUtils.loadAnimation() 加载动画,然后我们的View控件调用startAnimation开启动画即可~
```
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_alpha;
private Button btn_scale;
private Button btn_tran;
private Button btn_rotate;
private Button btn_set;
private ImageView img_show;
private Animation animation = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
btn_alpha = (Button) findViewById(R.id.btn_alpha);
btn_scale = (Button) findViewById(R.id.btn_scale);
btn_tran = (Button) findViewById(R.id.btn_tran);
btn_rotate = (Button) findViewById(R.id.btn_rotate);
btn_set = (Button) findViewById(R.id.btn_set);
img_show = (ImageView) findViewById(R.id.img_show);
btn_alpha.setOnClickListener(this);
btn_scale.setOnClickListener(this);
btn_tran.setOnClickListener(this);
btn_rotate.setOnClickListener(this);
btn_set.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_alpha:
animation = AnimationUtils.loadAnimation(this,
R.anim.anim_alpha);
img_show.startAnimation(animation);
break;
case R.id.btn_scale:
animation = AnimationUtils.loadAnimation(this,
R.anim.anim_scale);
img_show.startAnimation(animation);
break;
case R.id.btn_tran:
animation = AnimationUtils.loadAnimation(this,
R.anim.anim_translate);
img_show.startAnimation(animation);
break;
case R.id.btn_rotate:
animation = AnimationUtils.loadAnimation(this,
R.anim.anim_rotate);
img_show.startAnimation(animation);
break;
case R.id.btn_set:
animation = AnimationUtils.loadAnimation(this,
R.anim.anim_set);
img_show.startAnimation(animation);
break;
}
}
}
```
**运行效果图**:
![](http://www.runoob.com/wp-content/uploads/2015/11/66905299.jpg)
嘿嘿,有点意思是吧,还不动手试试,改点东西,或者自由组合动画,做出酷炫的效果吧~
## 4.动画状态的监听
> 我们可以对动画的执行状态进行监听,调用动画对象的:
* **setAnimationListener(new AnimationListener())**方法,重写下面的三个方法:
* **onAnimationStart**():动画开始
* **onAnimtaionRepeat**():动画重复
* **onAnimationEnd**():动画结束
即可完成动画执行状态的监听~
## 5.为View动态设置动画效果
> 先调用**AnimationUtils.loadAnimation**(动画xml文件),然后View控件调用startAnimation(anim) 开始动画~这是静态加载的方式,当然你也可以直接创建一个动画对象,用Java代码完成设置,再调用 startAnimation开启动画~
## 6.为Fragment设置过渡动画
这里要注意一点,就是Fragment是使用的**v4包**还是**app包**下的Fragment! 我们可以调用**FragmentTransaction**对象的**setTransition(int transit)** 为Fragment指定标准的过场动画,transit的可选值如下:
* **TRANSIT_NONE**:无动画
* **TRANSIT_FRAGMENT_OPEN**:打开形式的动画
* **TRANSIT_FRAGMENT_CLOSE**:关闭形式的动画
上面的标准过程动画是两个都可以调用的,而不同的地方则在于自定义转场动画
**setCustomAnimations**()方法!
* **app包下的Fragment**: **setCustomAnimations(int enter, int exit, int popEnter, int popExit)** 分别是添加,移除,入栈,以及出栈时的动画! 另外要注意一点的是,对应的动画类型是:属性动画(Property),就是动画文件 的根标签要是:<**objectAnimator**>,<**valueAnimator**>或者是前面两者放到一个<**set**>里;
* **v4包下的Fragment**: v4包下的则支持两种setCustomAnimations()
![](http://www.runoob.com/wp-content/uploads/2015/11/34767523.jpg)
另外要注意一点的是,对应的动画类型是:补间动画(Tween),和上面的View一样~
可能你会有疑惑,你怎么知道对应的动画类型,其实只要你到Fragment源码那里找下:
onCreateAnimation()方法的一个返回值就知道了:
**v4包**:
![](http://www.runoob.com/wp-content/uploads/2015/11/5983622.jpg)
**app包**:
![](http://www.runoob.com/wp-content/uploads/2015/11/55776797.jpg)
## 7.为Activity设置过场动画
Activty设置过场动画非常简单,调用的方法是:**overridePendingTransition**(int enterAnim, int exitAnim)
用法很简单:**在startActivity(intent)**或者**finish()**后添加
参数依次是:**新Activity进场**时的动画,以及**旧Activity退场**时的动画
下面提供几种比较简单而且常用的过场动画供大家使用~
![](http://www.runoob.com/wp-content/uploads/2015/11/54479717.jpg)
> 下载传送门:[Activity常用过渡动画.zip](http://pan.baidu.com/s/1dDdRF5f)
## 8.写个进入APP后登陆注册按钮从底部弹出动画效果的例子:
**运行效果图**:
![](http://www.runoob.com/wp-content/uploads/2015/11/6026348.jpg)
**代码实现**:
首先是我们的布局文件:**activity_main.xml**:
```
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DDE2E3"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/start_ctrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"
android:visibility="gone">
<Button
android:id="@+id/start_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F26968"
android:gravity="center"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:text="登陆"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<Button
android:id="@+id/start_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#323339"
android:gravity="center"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:text="注册"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>
```
接着是**MainActivity.java**:
```
public class MainActivity extends AppCompatActivity {
private LinearLayout start_ctrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start_ctrl = (LinearLayout) findViewById(R.id.start_ctrl);
//设置动画,从自身位置的最下端向上滑动了自身的高度,持续时间为500ms
final TranslateAnimation ctrlAnimation = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 1, TranslateAnimation.RELATIVE_TO_SELF, 0);
ctrlAnimation.setDuration(500l); //设置动画的过渡时间
start_ctrl.postDelayed(new Runnable() {
@Override
public void run() {
start_ctrl.setVisibility(View.VISIBLE);
start_ctrl.startAnimation(ctrlAnimation);
}
}, 2000);
}
}
```
注释写得很清楚了,这里就不BB解释了,如果你对TranslateAnimation.RELATIVE_TO_SELF这个有疑惑, 请自己谷歌或者百度,限于篇幅(我懒),这里就不写了,蛮简单的~
![](http://www.runoob.com/wp-content/uploads/2015/11/64331552.jpg)
## 9.本节代码示例下载
[AnimationDemo3.zip](http://static.runoob.com/download/AnimationDemo3.zip)
[AnimationDemo4.zip](http://static.runoob.com/download/AnimationDemo4.zip)
## 本节小结:
> 本节给大家细细地讲解了下Android中的第二种动画(渐变动画),四种动画的详解,以及 设置动画监听器,还有如何为View,Fragment和Activity设置动画,最后还写了一个进入后 从APP底部弹出登陆按钮和注册按钮的例子,篇幅可能有点长,不过都非常容易理解,相信 大家看完都能够收获满满~!好的,本节就到这里,谢谢~
>
> [](http://www.runoob.com/wp-content/uploads/2015/11/91586133.jpg)
- 1.0 Android基础入门教程
- 1.0.1 2015年最新Android基础入门教程目录
- 1.1 背景相关与系统架构分析
- 1.2 开发环境搭建
- 1.2.1 使用Eclipse + ADT + SDK开发Android APP
- 1.2.2 使用Android Studio开发Android APP
- 1.3 SDK更新不了问题解决
- 1.4 Genymotion模拟器安装
- 1.5.1 Git使用教程之本地仓库的基本操作
- 1.5.2 Git之使用GitHub搭建远程仓库
- 1.6 .9(九妹)图片怎么玩
- 1.7 界面原型设计
- 1.8 工程相关解析(各种文件,资源访问)
- 1.9 Android程序签名打包
- 1.11 反编译APK获取代码&资源
- 2.1 View与ViewGroup的概念
- 2.2.1 LinearLayout(线性布局)
- 2.2.2 RelativeLayout(相对布局)
- 2.2.3 TableLayout(表格布局)
- 2.2.4 FrameLayout(帧布局)
- 2.2.5 GridLayout(网格布局)
- 2.2.6 AbsoluteLayout(绝对布局)
- 2.3.1 TextView(文本框)详解
- 2.3.2 EditText(输入框)详解
- 2.3.3 Button(按钮)与ImageButton(图像按钮)
- 2.3.4 ImageView(图像视图)
- 2.3.5.RadioButton(单选按钮)&Checkbox(复选框)
- 2.3.6 开关按钮ToggleButton和开关Switch
- 2.3.7 ProgressBar(进度条)
- 2.3.8 SeekBar(拖动条)
- 2.3.9 RatingBar(星级评分条)
- 2.4.1 ScrollView(滚动条)
- 2.4.2 Date & Time组件(上)
- 2.4.3 Date & Time组件(下)
- 2.4.4 Adapter基础讲解
- 2.4.5 ListView简单实用
- 2.4.6 BaseAdapter优化
- 2.4.7ListView的焦点问题
- 2.4.8 ListView之checkbox错位问题解决
- 2.4.9 ListView的数据更新问题
- 2.5.0 构建一个可复用的自定义BaseAdapter
- 2.5.1 ListView Item多布局的实现
- 2.5.2 GridView(网格视图)的基本使用
- 2.5.3 Spinner(列表选项框)的基本使用
- 2.5.4 AutoCompleteTextView(自动完成文本框)的基本使用
- 2.5.5 ExpandableListView(可折叠列表)的基本使用
- 2.5.6 ViewFlipper(翻转视图)的基本使用
- 2.5.7 Toast(吐司)的基本使用
- 2.5.8 Notification(状态栏通知)详解
- 2.5.9 AlertDialog(对话框)详解
- 2.6.0 其他几种常用对话框基本使用
- 2.6.1 PopupWindow(悬浮框)的基本使用
- 2.6.2 菜单(Menu)
- 2.6.3 ViewPager的简单使用
- 2.6.4 DrawerLayout(官方侧滑菜单)的简单使用
- 3.1.1 基于监听的事件处理机制
- 3.2 基于回调的事件处理机制
- 3.3 Handler消息传递机制浅析
- 3.4 TouchListener PK OnTouchEvent + 多点触碰
- 3.5 监听EditText的内容变化
- 3.6 响应系统设置的事件(Configuration类)
- 3.7 AnsyncTask异步任务
- 3.8 Gestures(手势)
- 4.1.1 Activity初学乍练
- 4.1.2 Activity初窥门径
- 4.1.3 Activity登堂入室
- 4.2.1 Service初涉
- 4.2.2 Service进阶
- 4.2.3 Service精通
- 4.3.1 BroadcastReceiver牛刀小试
- 4.3.2 BroadcastReceiver庖丁解牛
- 4.4.2 ContentProvider再探——Document Provider
- 4.5.1 Intent的基本使用
- 4.5.2 Intent之复杂数据的传递
- 5.1 Fragment基本概述
- 5.2.1 Fragment实例精讲——底部导航栏的实现(方法1)
- 5.2.2 Fragment实例精讲——底部导航栏的实现(方法2)
- 5.2.3 Fragment实例精讲——底部导航栏的实现(方法3)
- 5.2.4 Fragment实例精讲——底部导航栏+ViewPager滑动切换页面
- 5.2.5 Fragment实例精讲——新闻(购物)类App列表Fragment的简单实现
- 6.1 数据存储与访问之——文件存储读写
- 6.2 数据存储与访问之——SharedPreferences保存用户偏好参数
- 6.3.1 数据存储与访问之——初见SQLite数据库
- 6.3.2 数据存储与访问之——又见SQLite数据库
- 7.1.1 Android网络编程要学的东西与Http协议学习
- 7.1.2 Android Http请求头与响应头的学习
- 7.1.3 Android HTTP请求方式:HttpURLConnection
- 7.1.4 Android HTTP请求方式:HttpClient
- 7.2.1 Android XML数据解析
- 7.2.2 Android JSON数据解析
- 7.3.1 Android 文件上传
- 7.3.2 Android 文件下载(1)
- 7.3.3 Android 文件下载(2)
- 7.4 Android 调用 WebService
- 7.5.1 WebView(网页视图)基本用法
- 7.5.2 WebView和JavaScrip交互基础
- 7.5.3 Android 4.4后WebView的一些注意事项
- 7.5.4 WebView文件下载
- 7.5.5 WebView缓存问题
- 7.5.6 WebView处理网页返回的错误码信息
- 7.6.1 Socket学习网络基础准备
- 7.6.2 基于TCP协议的Socket通信(1)
- 7.6.3 基于TCP协议的Socket通信(2)
- 7.6.4 基于UDP协议的Socket通信
- 8.1.1 Android中的13种Drawable小结 Part 1
- 8.1.2 Android中的13种Drawable小结 Part 2
- 8.1.3 Android中的13种Drawable小结 Part 3
- 8.2.1 Bitmap(位图)全解析 Part 1
- 8.2.2 Bitmap引起的OOM问题
- 8.3.1 三个绘图工具类详解
- 8.3.2 绘图类实战示例
- 8.3.3 Paint API之—— MaskFilter(面具)
- 8.3.4 Paint API之—— Xfermode与PorterDuff详解(一)
- 8.3.5 Paint API之—— Xfermode与PorterDuff详解(二)
- 8.3.6 Paint API之—— Xfermode与PorterDuff详解(三)
- 8.3.7 Paint API之—— Xfermode与PorterDuff详解(四)
- 8.3.8 Paint API之—— Xfermode与PorterDuff详解(五)
- 8.3.9 Paint API之—— ColorFilter(颜色过滤器)(1/3)
- 8.3.10 Paint API之—— ColorFilter(颜色过滤器)(2-3)
- 8.3.11 Paint API之—— ColorFilter(颜色过滤器)(3-3)
- 8.3.12 Paint API之—— PathEffect(路径效果)
- 8.3.13 Paint API之—— Shader(图像渲染)
- 8.3.14 Paint几个枚举/常量值以及ShadowLayer阴影效果
- 8.3.15 Paint API之——Typeface(字型)
- 8.3.16 Canvas API详解(Part 1)
- 8.3.17 Canvas API详解(Part 2)剪切方法合集
- 8.3.18 Canvas API详解(Part 3)Matrix和drawBitmapMash
- 8.4.1 Android动画合集之帧动画
- 8.4.2 Android动画合集之补间动画
- 8.4.3 Android动画合集之属性动画-初见
- 8.4.4 Android动画合集之属性动画-又见
- 9.1 使用SoundPool播放音效(Duang~)
- 9.2 MediaPlayer播放音频与视频
- 9.3 使用Camera拍照
- 9.4 使用MediaRecord录音
- 10.1 TelephonyManager(电话管理器)
- 10.2 SmsManager(短信管理器)
- 10.3 AudioManager(音频管理器)
- 10.4 Vibrator(振动器)
- 10.5 AlarmManager(闹钟服务)
- 10.6 PowerManager(电源服务)
- 10.7 WindowManager(窗口管理服务)
- 10.8 LayoutInflater(布局服务)
- 10.9 WallpaperManager(壁纸管理器)
- 10.10 传感器专题(1)——相关介绍
- 10.11 传感器专题(2)——方向传感器
- 10.12 传感器专题(3)——加速度/陀螺仪传感器
- 10.12 传感器专题(4)——其他传感器了解
- 10.14 Android GPS初涉
- 11.0《2015最新Android基础入门教程》完结散花~