Android三种动画(属性、视图、帧动画)介绍基本使用
Android动画基本可以分为三类:
View Animation(视图动画)、Property Animation:(属性动画)和Drawable Animation(帧动画)。其中视图动画早在Android老版本就已经支持了,只能对view控件编辑动画。属性动画是Android在3.0版本后推出的API,是Google为了解决视图动画推出的,可以对任意的控件进行动画编辑。帧动画即一帧一帧的显示形成动画的。
属性动画可以完全代替视图动画,解决视图动画不能解决的问题,在现实使用中,属性动画较为使用频繁,本篇幅介绍属性动画的基本使用、帧动画的基本使用和补间动画的基本使用。
1、属性动画的基本使用:
属性动画的原理是通过特定的时长来改变一个属性的值,从而达到动画效果,使用的比较频繁的有三个类:ValueAnimator、ObjectAnimator、AnimatorSet。
**两种实现方法:**Android代码实现、xml文件实现。
android代码实现(以ObjectAnimator使用为例 ):
[1]通过onFloat返回ObjectAnimator 对象
ObjectAnimator oa = ObjectAnimator.onFloat(Object target, String propertyName, float… values) ;
[2]设置时长oa.setDuration(5000);
[3]启动oa.start();
xml实现方式:
[1]在res目录新建一个animator(animator为属性动画,anim为补间动画)目录,在改目录下创建xml文件。
对应的根节点:
animator 对应ValueAnimator
objectAnimator 对应ObjectAnimator
set 对应AnimatorSet
[2]在Android代码中使用属性动画资源:
oa.setTarget(iv);
oa.start();
下面解析一下ValueAnimator、ObjectAnimator、AnimatorSet这三个在属性动画中常用的类的用法。
ValueAnimator: 负责对值在提供时间得过度计算运行,还负责管理动画的播放次数、播放模式、动画监听器等,是个比较重要的类。它表示从设置的时间内(Duration设置)如何平滑的过度给定的初始值到结束值(ofFloat等的参数值)。如下例子,通过设置监听,打印出在1000ms内0过度到1的变化(至于Android如何实现这个变化在后面讲),结果如图1所示
//ValueAnimator
private void ValueAnimator_test() {
//设置初始值0和结束值1
ValueAnimator valueA = ValueAnimator.ofFloat(0f,1f);
//设置时间为1000ms
valueA.setDuration(1000);
//设置监听器,一旦值发生变化,即获取后打印出来
valueA.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatorValue = (float) animation.getAnimatedValue();
Log.e("tag","value : "+animatorValue);
}
});
//启动
valueA.start();
}
如上演示了ValueAnimator的基本用法,在实际应用不会常用到此类,应用得多的是ObjectAnimator,但ValueAnimator是ObjectAnimator的基类,ObjectAnimator继承自ValueAnimator类。
ObjectAnimator:使用比较频繁的类,最终调用的还是ValueAnimator。该类实现Android各种动画
例如例子,以缩放从1倍到3倍到1倍的变化,在4000ms内完成此动作,结果如图2所示。也可左右移动,通过控件的getTranslationX获取当前x的位置,在当前位置移动到500处再移动回原来的位置,此动作在设置在4000ms内完成。结果如图3所示。
//ObjectAnimator
private void ObjectAnimator_test() {
/*
* alpha:透明度
*rotation:旋转角度
*scaleY:竖直方向4秒内扩大3倍再缩放回原来的比例。
* */
ObjectAnimator objectA = ObjectAnimator.ofFloat(animText,"scaleY",1f,3f,1f);
objectA.setDuration(4000);
objectA.start();
/*先调用TextView的getTranslationX方法来获取当前View的位置,在ofFloat第二个参数指定移动的方法,
* 第三个参数指定从当前位置移动到500处再移动回到原来位置。
* */
/*float tranX = animText.getTranslationX();
ObjectAnimator objectA = ObjectAnimator.ofFloat(animText,"translationX",tranX,500,tranX);
objectA.setDuration(4000);
objectA.start();*/
}
至于其他效果,例如旋转,设置透明变化等,也可以参照此来设置显示相应的效果。
AnimatorSet:组合动画(四种组合方式如注释),即能同时将旋转、移动、透明等变化一起显示动作,也可以按先后顺序来显示等。
如下,显示透明变化后,同时进行缩放和旋转。效果如图3
/*
* 组合动画
* after(Animator anim) 将现有动画插入到传入的动画之后执行
* after(long delay) 将现有动画延迟指定毫秒后执行
* before(Animator anim) 将现有动画插入到传入的动画之前执行
* with(Animator anim) 将现有动画和传入的动画同时执行
* */
private void AnimatorSet_test()
{
ObjectAnimator Sca = ObjectAnimator.ofFloat(animText,"scaleY",1f,3f);
ObjectAnimator Rot = ObjectAnimator.ofFloat(animText,"rotation",0f,270f);
ObjectAnimator alp = ObjectAnimator.ofFloat(animText,"alpha",1f,0f,1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(3000);
set.play(Sca).with(Rot).before(alp);
set.start();
}
给动画设置监听器:
/*
* 监听器:在某种状态发出某个动作
*例子:在Y轴方向放大结束后,将textview字体改为浅黄色。
* */
private void Listener_test()
{
final ObjectAnimator objAni = ObjectAnimator.ofFloat(animText,"scaleY",1f,3f);
objAni.setDuration(3000);
objAni.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animText.setTextColor(0xffb8860b);
}
});
objAni.start();
}
在xml中设置动画方式:
在上面已经简单谈过xml的的使用方式,在这里以组合动画为例简单写一下xml的使用方式。
<?xml version="1.0" encoding="utf-8"?>
<!--
xml三种定义动画标签:
<animator> 对应代码中的ValueAnimator
<objectAnimator> 对应代码中的ObjectAnimator
<set> 对应代码中的AnimatorSet
-->
<!--<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:valueFrom="0f"
android:valueTo="1f"
android:valueType="floatType"
/>-->
<!--
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueTo="3"
android:valueFrom="1"
android:valueType="floatType"
android:propertyName="scaleX"
/>
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="4000"
android:propertyName="translationX"
android:valueTo="0"
android:valueType="floatType"
android:valueFrom="500">
</objectAnimator>
<set
android:ordering="together">
<objectAnimator
android:duration="4000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"
></objectAnimator>
<set
android:ordering="sequentially">
<objectAnimator
android:duration="3000"
android:propertyName="alpha"
android:valueFrom="1"
android:valueType="floatType"
android:valueTo="0">
</objectAnimator>
<objectAnimator
android:valueTo="1"
android:valueFrom="0"
android:duration="3000"
android:propertyName="alpha"
android:valueType="floatType">
</objectAnimator>
</set>
</set>
</set>
/*
* xml布局方式的Java调用代码如下
* */
private void xml_test()
{
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.anim);
animator.setTarget(animText);
animator.start();
}
xml使用的效果如下:
2、帧动画基本使用:
帧动画即一个帧一个帧的拼在一起显示成动画,这里以进度为例,连续显示7张图片。
/*使用布局方式*/
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/load1"
android:duration="100"
/>
<item android:drawable="@drawable/load2"
android:duration="100"
/>
<item android:drawable="@drawable/load3"
android:duration="100"
/>
<item android:drawable="@drawable/load4"
android:duration="100"
/>
<item android:drawable="@drawable/load5"
android:duration="100"
/>
<item android:drawable="@drawable/load6"
android:duration="100"
/>
<item android:drawable="@drawable/load7"
android:duration="100"
/>
</animation-list>
/*Java代码调用方式
*这里需要在onWindowFocusChanged实现,是因为AnimationDrawable播放动画是依附在window上面的,而在Activity onCreate方法中调用时*Window还未初始化完毕,要想实现播放必须在onWindowFocusChanged中添加如下代码:*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
imagev.setImageResource(R.drawable.framentanimator);
AnimationDrawable ad = (AnimationDrawable) imagev.getDrawable();
ad.start();
}
/*
* 使用纯Java代码实现帧动画
* */
public void useJavashowfrement()
{
AnimationDrawable aDrawable =new AnimationDrawable();
for (int i=7;i>0;i--)
{
int id = getResources().getIdentifier("load"+i,"drawable",getPackageName());
Drawable drawable = getResources().getDrawable(id);
aDrawable.addFrame(drawable,100);
}
aDrawable.setOneShot(false);
imagev.setImageDrawable(aDrawable);
aDrawable.start();
}
效果如下:
3、补间动画的基本使用:
下面通过几个按钮来加载补间的几种动画,MainActivity的程序如下:
package com.example.namitortest;
import android.app.Activity;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
/**
* Created by new on 2017/7/14.
*/
public class TweenTest extends Activity implements View.OnClickListener{
private ImageView showV;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tween);
showV = (ImageView) findViewById(R.id.showV);
Button alphaB = (Button) findViewById(R.id.alphaBtn);
Button scaleB = (Button) findViewById(R.id.scaleBtn);
Button translateB = (Button) findViewById(R.id.translateBtn);
Button rotateB = (Button) findViewById(R.id.rotateBtn);
Button setB = (Button) findViewById(R.id.setBtn);
alphaB.setOnClickListener(this);
scaleB.setOnClickListener(this);
rotateB.setOnClickListener(this);
translateB.setOnClickListener(this);
setB.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.alphaBtn:
Animation animation = new AnimationUtils().loadAnimation(getApplicationContext(),R.anim.tween_alpha);
showV.startAnimation(animation);
break;
case R.id.rotateBtn:
Animation animation1 = new AnimationUtils().loadAnimation(getApplicationContext(),R.anim.tween_rotate);
showV.startAnimation(animation1);
break;
case R.id.setBtn:
Animation animation2 = new AnimationUtils().loadAnimation(getApplicationContext(),R.anim.tween_set);
showV.startAnimation(animation2);
break;
case R.id.scaleBtn:
Animation animation3 = new AnimationUtils().loadAnimation(getApplicationContext(),R.anim.tween_scale);
showV.startAnimation(animation3);
break;
case R.id.translateBtn:
Animation animation4 = new AnimationUtils().loadAnimation(getApplicationContext(),R.anim.tween_translate);
showV.startAnimation(animation4);
break;
default:
break;
}
}
}
xml布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="alpha"
android:id="@+id/alphaBtn"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/translateBtn"
android:text="translate"
android:layout_toRightOf="@id/alphaBtn"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/scaleBtn"
android:text="scale"
android:layout_toRightOf="@id/translateBtn"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/setBtn"
android:text="set"
android:layout_below="@id/alphaBtn"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/rotateBtn"
android:text="rotate"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/setBtn"
android:layout_below="@id/scaleBtn"
android:layout_marginTop="20dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/showV"
android:src="@mipmap/ic_launcher"
android:layout_below="@id/setBtn"
android:layout_marginTop="150dp"
android:layout_marginLeft="150dp"
/>
</RelativeLayout>
程序比较简单,通过5个按钮分别对应translate、scale、set、rotate、aphla五种动画。主要通过AnimationUtils().loadAnimation来获取Animation对象,再将控件的Animation设置为此动画方式即可。效果如下:
设置透明变化alpha效果:
设置移动变化translate效果:
设置旋转rotate效果:
设置缩放scale效果:
设置动画组合set:
这些是补间动画、帧动画和属性动画的基本使用,其中属性动画还有更高级的使用是补间动画实现不了的。