今天花了一天时间,把android中视图动画、属性动画搞了一遍。算是把这部分东西搞得知道是怎么回事儿。
先上效果图:
结果图中分为四个部分,分别是代码控制视图动画、XML控制视图动画、代码控制属性动画、XML控制属性动画。
每一部分都有旋转、缩放、平移、透明度、组合等几个部分。
非常适合初学者对于视图动画和属性动画的用法的掌握。
下面开始,按照上面的四个部分一一说明。
代码控制视图动画
透明度
AlphaAnimation alphaAnimation = new AlphaAnimation(0.2f, 1);
alphaAnimation.setDuration(3000);
//加减速差值器
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
alpha.startAnimation(alphaAnimation);
直接使用AlphaAnimation 即可控制组件的透明度的效果。
构造器的参数值就是透明度的开始值和最终值。
代码中setDuration可以控制动画的持续时间,包括下面的全部的动画,都可以设置持续时间。下面的部分就不在说着地方了。
还有一个setInterpolator是设置差值器,其实就是动画的加速显示或者非加速显示,或者线性均匀显示之类的效果。默认情况下,线性均匀显示。
缩放
//默认组件原点为中心
// ScaleAnimation scaleAnimation = new ScaleAnimation(0.2f,1,0.2f,1);
//指定为组件的中心
ScaleAnimation scaleAnimation = new ScaleAnimation(0.2f, 1, 0.2f, 1, scale.getWidth() / 2, scale.getHeight() / 2);
scaleAnimation.setDuration(3000);
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"开始啦。",
Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
scale.startAnimation(scaleAnimation);
代码中注释部分,根据构造器构建了几个对象,注释中有说明。效果就是控制组件的缩放。
值的注意的是,我在这里设置了动画监听器,当动画开始的时候,toast一个,动画结束的时候,toast一个。大家可以看到动画监听器的用法。
平移
TranslateAnimation translateAnimation = new TranslateAnimation(30, 90, 30, 90);
translateAnimation.setDuration(3000);
traslate.startAnimation(translateAnimation);
平移也简单,就是控制组件的移动的。构造器参数代表意思是:
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)看看参数的字面意思也知道分别代表什么了。
他还有一个构造器:
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)
这个构造器有点麻烦了,参数多,不过还有,每个移动的参数都有一个fromXType与之对应,API文档中有说明,fromXType的值是:One of Animation.ABSOLUTE 绝对值
Animation.RELATIVE_TO_SELF 相对自己的值
Animation.RELATIVE_TO_PARENT. 相对父组件的值
能够取的值也就这三个值,那就明白了,也就是说
int fromXType, float fromXValue 中的value值与前面的type有点关系。
旋转
//不指定中心,则默认组件原点为中心
// RotateAnimation rotateAnimation = new RotateAnimation(0,360);
//指定中心。
// RotateAnimation rotateAnimation = new RotateAnimation(0,360,rotate.getWidth()/2,rotate.getHeight()/2);
//指定旋转中心的类型
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(2000);
//加速差值器
rotateAnimation.setInterpolator(new AccelerateInterpolator());
rotate.startAnimation(rotateAnimation);
旋转组件,构造器:
RotateAnimation(float fromDegrees, float toDegrees)
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
旋转构造器有这么几个,一看就明白。不过,需要注意的是,角度的问题,这里需要知道手机屏幕的角度坐标系,请参考我的博文:android-自定义View初步探索
最后来一个组合
AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.3f,1f);
alphaAnimation1.setDuration(5000);
ScaleAnimation scaleAnimation1 = new ScaleAnimation(0,1,0,1,allAni.getWidth()/2,allAni.getHeight()/2);
scaleAnimation1.setDuration(5000);
RotateAnimation rotateAnimation1 = new RotateAnimation(0,360,allAni.getWidth()/2,allAni.getHeight()/2);
rotateAnimation1.setDuration(5000);
AnimationSet set = new AnimationSet(true);
set.addAnimation(alphaAnimation1);
set.addAnimation(scaleAnimation1);
set.addAnimation(rotateAnimation1);
set.setFillEnabled(true);
set.setDuration(2000);
set.setRepeatCount(0);
allAni.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"开始啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"结束啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
组合就是吧上面的集中效果集合一起进行设置,通过AnimationSet来完成,同时设置了动画的监听器,动画开始,动画结束、动画重复分别调用其中的方法。
效果如下:
下面给出完成的activity的代码:
public class CodeViewAnimation extends AppCompatActivity implements View.OnClickListener {
@Bind(R.id.alpha)
TextView alpha;
@Bind(R.id.scale)
TextView scale;
@Bind(R.id.traslate)
TextView traslate;
@Bind(R.id.rotate)
TextView rotate;
@Bind(R.id.all_ani)
TextView allAni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_code);
ButterKnife.bind(this);
}
@OnClick({R.id.alpha, R.id.scale, R.id.traslate, R.id.rotate,R.id.all_ani})
public void onClick(View v) {
Log.i("dd", "onclick");
switch (v.getId()) {
case R.id.alpha:
AlphaAnimation alphaAnimation = new AlphaAnimation(0.2f, 1);
alphaAnimation.setDuration(3000);
//加减速差值器
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
alpha.startAnimation(alphaAnimation);
break;
case R.id.rotate:
//不指定中心,则默认组件原点为中心
// RotateAnimation rotateAnimation = new RotateAnimation(0,360);
//指定中心。
// RotateAnimation rotateAnimation = new RotateAnimation(0,360,rotate.getWidth()/2,rotate.getHeight()/2);
//指定旋转中心的类型
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(2000);
//加速差值器
rotateAnimation.setInterpolator(new AccelerateInterpolator());
rotate.startAnimation(rotateAnimation);
break;
case R.id.traslate:
TranslateAnimation translateAnimation = new TranslateAnimation(30, 90, 30, 90);
translateAnimation.setDuration(3000);
traslate.startAnimation(translateAnimation);
break;
case R.id.scale:
//默认组件原点为中心
// ScaleAnimation scaleAnimation = new ScaleAnimation(0.2f,1,0.2f,1);
//指定为组件的中心
ScaleAnimation scaleAnimation = new ScaleAnimation(0.2f, 1, 0.2f, 1, scale.getWidth() / 2, scale.getHeight() / 2);
scaleAnimation.setDuration(3000);
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"开始啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"结束啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
scale.startAnimation(scaleAnimation);
break;
case R.id.all_ani:
Log.i("dd", "allani");
AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.3f,1f);
alphaAnimation1.setDuration(5000);
ScaleAnimation scaleAnimation1 = new ScaleAnimation(0,1,0,1,allAni.getWidth()/2,allAni.getHeight()/2);
scaleAnimation1.setDuration(5000);
RotateAnimation rotateAnimation1 = new RotateAnimation(0,360,allAni.getWidth()/2,allAni.getHeight()/2);
rotateAnimation1.setDuration(5000);
AnimationSet set = new AnimationSet(true);
set.addAnimation(alphaAnimation1);
set.addAnimation(scaleAnimation1);
set.addAnimation(rotateAnimation1);
set.setFillEnabled(true);
set.setDuration(2000);
set.setRepeatCount(0);
allAni.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"开始啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(CodeViewAnimation.this,"结束啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
}
XML控制视图动画
xml控制视图动画,需要在工程文件夹
按照上面的图中res目录下面新建一个anim文件夹存放视图动画的xml文件,新建一个animator文件夹存放属性动画的xml文件。
透明度
res/anim/alpha.xml文件内容如下:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="2000"
android:fromAlpha="0.3"
android:toAlpha="1"
android:repeatCount="3"
android:interpolator="@android:interpolator/accelerate_decelerate"
/>
set>
大家看xml文件即可知道其中的意思,根是set集合,android:interpolator是差值器,这个跟代码中使用差值器是一样的,android系统本身提供一些差值器。一般用不用都行。主要是一些效果吧。别的就没什么说的了。下面看代码中怎么用:
Animation alpha_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.alpha);
alpha.startAnimation(alpha_animation);
使用AnimationUtils类的loadAnimation方法进行load就可以啦。
效果是一样一样的。
缩放
res/anim/scale.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="3000"
android:repeatCount="1"
android:interpolator="@android:interpolator/bounce"
android:fromXScale="0"
android:fromYScale="0"
android:toXScale="1"
android:toYScale="1"
android:pivotX="50%"
android:pivotY="50%"
/>
set>
其中要注意的是,pivotX pivotY设置缩放的中心,其值只能是百分比。值从百分之一到百分之百。
代码中调用:
Animation scale_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.scale);
scale.startAnimation(scale_animation);
平移
res/anim/traslate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:interpolator="@android:interpolator/cycle"
android:duration="3000"
android:repeatCount="0"
android:fromXDelta="30"
android:fromYDelta="30"
android:toXDelta="90"
android:toYDelta="90"
/>
set>
代码中调用:
Animation traslate_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.traslate);
traslate.startAnimation(traslate_animation);
旋转
res/anim/rotate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="3000"
android:interpolator="@android:interpolator/anticipate"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="90"
android:toDegrees="270"
/>
set>
其中也要注意pivotY pivotX设置旋转的中心,其值为百分比。代码中调用:
Animation rotate_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.rotate);
rotate.startAnimation(rotate_animation);
组合一组
res/anim/all.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="2000"
android:fromAlpha="0.3"
android:toAlpha="1"
android:repeatCount="0"
android:interpolator="@android:interpolator/accelerate_decelerate"
/>
<scale
android:duration="3000"
android:repeatCount="1"
android:interpolator="@android:interpolator/bounce"
android:fromXScale="0"
android:fromYScale="0"
android:toXScale="1"
android:toYScale="1"
android:pivotX="50%"
android:pivotY="50%"
/>
<rotate
android:duration="3000"
android:interpolator="@android:interpolator/anticipate"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="90"
android:toDegrees="270"
/>
set>
代码中调用:
Animation all_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this,R.anim.all);
allAni.startAnimation(all_animation);
all_animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(XmlViewActivity.this, "开始啦。", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(XmlViewActivity.this,"结束啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
代码中在调用的时候,设置了监听器,这与代码中完成动画中设置的监听器一样的功能。
最后给出这个activity的代码如下:
package com.husy.androidallanimation;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class XmlViewActivity extends AppCompatActivity {
@Bind(R.id.alpha)
TextView alpha;
@Bind(R.id.scale)
TextView scale;
@Bind(R.id.traslate)
TextView traslate;
@Bind(R.id.rotate)
TextView rotate;
@Bind(R.id.all_ani)
TextView allAni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_code);
ButterKnife.bind(this);
}
@OnClick({R.id.alpha, R.id.scale, R.id.traslate, R.id.rotate, R.id.all_ani})
public void onclick(View v) {
switch (v.getId()) {
case R.id.alpha:
Animation alpha_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.alpha);
alpha.startAnimation(alpha_animation);
break;
case R.id.scale:
Animation scale_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.scale);
scale.startAnimation(scale_animation);
break;
case R.id.traslate:
Animation traslate_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.traslate);
traslate.startAnimation(traslate_animation);
break;
case R.id.rotate:
Animation rotate_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this, R.anim.rotate);
rotate.startAnimation(rotate_animation);
break;
case R.id.all_ani:
Animation all_animation = AnimationUtils
.loadAnimation(XmlViewActivity.this,R.anim.all);
allAni.startAnimation(all_animation);
all_animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(XmlViewActivity.this, "开始啦。", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(XmlViewActivity.this,"结束啦。",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
}
====================下面是属性动画===================
- 代码控制属性动画
平移
代码中控制属性动画平移
ObjectAnimator translateA =
ObjectAnimator.ofFloat(traslate, "translationX", 300, -200);
translateA.setDuration(3000);
translateA.setRepeatCount(1);
translateA.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Toast.makeText(CodeObjectAnimActivity.this, "开始啦", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(CodeObjectAnimActivity.this, "结束啦", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
translateA.start();
ObjectAnimator就是完成属性动画的类,ofFloat ofInt 等构造ObjectAnimator对象。
先通过文档API看看该类的一些方法;
static ObjectAnimator ofArgb(Object target, String propertyName, int… values)
static ObjectAnimator ofFloat(Object target, String propertyName, float… values)
static < T> ObjectAnimator ofInt(T target, Property< T, Integer> property, int… values)
其中ObjectAnimator类的方法远不止这几个,
其中,参数中的target设置的是要进行动画的组件
参数propertyName是设置的动画的属性
不定多个之的values值是属性的动画值。
上面的代码中,我们的属性translationX,它的值从300移动到-200的位置。
效果图如下:
这是是完成了水平方向上的移动,如果要控制多个属性呢,请往下继续看。
旋转
代码:
ObjectAnimator rotateA =
ObjectAnimator.ofFloat(rotate, "rotation", 20, 180);
rotateA.setDuration(3000);
rotateA.start();
透明度
ObjectAnimator alphaA =
ObjectAnimator.ofFloat(alpha, "alpha", 0.2f, 1);
alphaA.setDuration(3000);
alphaA.start();
缩放
代码:
ObjectAnimator scaleA =
ObjectAnimator.ofFloat(scale,"scaleX",0.2f,1);
scaleA.start();
这里控制的是x轴的缩放,同时控制Y轴的缩放,请往下看。
来一个组合
代码:
PropertyValuesHolder tx =
PropertyValuesHolder.ofFloat("translationX", 300, -200);
PropertyValuesHolder ty =
PropertyValuesHolder.ofFloat("translationY", 50, -10);
PropertyValuesHolder sx =
PropertyValuesHolder.ofFloat("scaleX", 0.1f, 1);
ObjectAnimator.ofPropertyValuesHolder(zuhe1, tx, ty, sx)
.setDuration(3000).start();
值动画
这个动画有点特殊,只控制值的改变
代码:
final ValueAnimator valueAnimator = ValueAnimator
.ofInt(20, 100);
valueAnimator.setDuration(5000);
valueAnimator.setTarget(value);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
value.setText(""+(int)animation.getAnimatedValue());
}
});
valueAnimator.start();
对ValueAnimator增加一个监听器,在值改变的时候,不断的调用该监听器;效果如下:
最后给出该activity的全部代码:
package com.husy.androidallanimation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class CodeObjectAnimActivity extends AppCompatActivity {
@Bind(R.id.traslate)
TextView traslate;
@Bind(R.id.rotate)
TextView rotate;
@Bind(R.id.alpha)
TextView alpha;
@Bind(R.id.zuhe1)
TextView zuhe1;
@Bind(R.id.zuhe2)
TextView value;
@Bind(R.id.scale)
TextView scale;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_object_anim);
ButterKnife.bind(this);
}
@OnClick({R.id.traslate, R.id.alpha, R.id.rotate,R.id.scale, R.id.zuhe1, R.id.zuhe2})
public void onclick(View v) {
switch (v.getId()) {
case R.id.traslate:
ObjectAnimator translateA =
ObjectAnimator.ofFloat(traslate, "translationX", 300, -200);
translateA.setDuration(3000);
translateA.setRepeatCount(1);
translateA.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Toast.makeText(CodeObjectAnimActivity.this, "开始啦", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(CodeObjectAnimActivity.this, "结束啦", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
translateA.start();
break;
case R.id.alpha:
ObjectAnimator alphaA =
ObjectAnimator.ofFloat(alpha, "alpha", 0.2f, 1);
alphaA.setDuration(3000);
alphaA.start();
break;
case R.id.rotate:
ObjectAnimator rotateA =
ObjectAnimator.ofFloat(rotate, "rotation", 20, 180);
rotateA.setDuration(3000);
rotateA.start();
break;
case R.id.scale:
ObjectAnimator scaleA =
ObjectAnimator.ofFloat(scale,"scaleX",0.2f,1);
scaleA.start();
break;
case R.id.zuhe1:
PropertyValuesHolder tx =
PropertyValuesHolder.ofFloat("translationX", 300, -200);
PropertyValuesHolder ty =
PropertyValuesHolder.ofFloat("translationY", 50, -10);
PropertyValuesHolder sx =
PropertyValuesHolder.ofFloat("scaleX", 0.1f, 1);
ObjectAnimator.ofPropertyValuesHolder(zuhe1, tx, ty, sx)
.setDuration(3000).start();
break;
case R.id.zuhe2:
final ValueAnimator valueAnimator = ValueAnimator
.ofInt(20, 100);
valueAnimator.setDuration(5000);
valueAnimator.setTarget(value);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
value.setText(""+(int)animation.getAnimatedValue());
}
});
valueAnimator.start();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
}
属性动画,必须在res目录下面新建一个animator文件夹,存放属性动画的xml文件
平移
res/animator/translate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="3000"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:repeatCount="1"
android:propertyName="translationX"
android:valueFrom="200"
android:valueTo="-10"
android:valueType="floatType"
>
objectAnimator>
<objectAnimator
android:duration="3000"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:repeatCount="1"
android:propertyName="translationY"
android:valueFrom="200"
android:valueTo="-10"
android:valueType="floatType"
>
objectAnimator>
set>
同时控制水平 垂直方向的移动。
代码中的调用如下:
Animator tra = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this, R.animator.translate);
tra.setTarget(traslate);
tra.start();
注意:使用的是AnimatorInflater类的loadAnimator方法进行调用,然后设置目标组件,调用start方法开始即可。
效果;
旋转
res/animator/rotate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:duration="3000"
android:propertyName="rotationX"
android:valueFrom="0"
android:valueTo="360"
android:startOffset="90"
>
objectAnimator>
set>
代码:
Animator rota = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.rotate);
rota.setTarget(rotate);
rota.start();
没什么说的了。
值的一提的是:设置Animation的startOffset来控制Animation的运行顺序——同时或按顺序运行动画。默认情况下,Animation是同时开始的,但可以通过设置startOffset属性来指定动画在*ms后开始运行。
透明度
res/animator/alpha.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="3000"
android:valueFrom="0.3"
android:valueTo="1"
android:propertyName="alpha"
android:valueType="floatType"
>
objectAnimator>
set>
代码:
Animator alph = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.alpha);
alph.setTarget(alpha);
alph.start();
缩放
res/animator/scale.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueType="floatType"
android:propertyName="scaleX"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="3000"
>
objectAnimator>
set>
代码;
Animator sca = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.scale);
sca.setTarget(scale);
sca.start();
来一个组合
res/animator/zuhe.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="3000"
android:valueFrom="0.3"
android:valueTo="1"
android:propertyName="alpha"
android:valueType="floatType"
>
objectAnimator>
<objectAnimator
android:valueType="floatType"
android:propertyName="scaleX"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="3000"
>
objectAnimator>
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:duration="3000"
android:propertyName="rotationX"
android:valueFrom="0"
android:valueTo="360"
android:startOffset="90"
>
objectAnimator>
set>
代码:
Animator zuhea = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.zuhe);
zuhea.setTarget(zuhe);
zuhea.start();
值动画
res/animator/value.xml
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:valueType="intType"
android:valueFrom="30"
android:valueTo="100"
>
objectAnimator>
代码:
ValueAnimator valuea = (ValueAnimator)AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.value);
valuea.setTarget(value);
valuea.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
value.setText(""+animation.getAnimatedValue());
}
});
valuea.start();
值动画必须通过监听器获取值的改变,然后利用该值进行相应的功能呢的设置。
效果:
最后给出该activity的全部代码:
package com.husy.androidallanimation;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class XMLAnimatorActivity extends AppCompatActivity {
@Bind(R.id.traslate)
TextView traslate;
@Bind(R.id.rotate)
TextView rotate;
@Bind(R.id.alpha)
TextView alpha;
@Bind(R.id.scale)
TextView scale;
@Bind(R.id.zuhe1)
TextView zuhe;
@Bind(R.id.zuhe2)
TextView value;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_object_anim);
ButterKnife.bind(this);
}
@OnClick({R.id.traslate,R.id.rotate,R.id.alpha,R.id.scale,R.id.zuhe2,R.id.zuhe1})
public void onclick(View v){
switch (v.getId()){
case R.id.traslate:
Animator tra = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this, R.animator.translate);
tra.setTarget(traslate);
tra.start();
break;
case R.id.rotate:
Animator rota = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.rotate);
rota.setTarget(rotate);
rota.start();
break;
case R.id.alpha:
Animator alph = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.alpha);
alph.setTarget(alpha);
alph.start();
break;
case R.id.scale:
Animator sca = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.scale);
sca.setTarget(scale);
sca.start();
break;
case R.id.zuhe1:
Animator zuhea = AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.zuhe);
zuhea.setTarget(zuhe);
zuhea.start();
break;
case R.id.zuhe2:
ValueAnimator valuea = (ValueAnimator)AnimatorInflater
.loadAnimator(XMLAnimatorActivity.this,R.animator.value);
valuea.setTarget(value);
valuea.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
value.setText(""+animation.getAnimatedValue());
}
});
valuea.start();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
}
总结一下;
1、视图动画,动画完成之后,如果不设置setfillafter(true)的话,会自动还原为原来的状态。而属性动画不会自动还原。
2、属性动画常用的属性值有:
(float) scaleX/scaleY
(float) translationX/translationY translationZ
(float) X/Y
(float)rotation rotationX/rotationY
(float) alpha)
(float)elevation
其中elevation属性是组件的高度,也就是z的高度。使用这个属性给组件以立体感。
还要注意的是,这些值是float类型,如果设置为int类型或者别的,都无效!!
3、属性动画,不仅仅局限于上面的几个属性,完全可以自定义属性,完成自己的功能。
只要组件具备基本得getxxx setxxx方法,同时在xxx改变的时候,组件确实有改变的效果,那就可以啦!!!
4、属性动画实现的效果,特别是平移,会使组件确实移动,对于组件添加的事件,比如点击事件,确实在移动后的位置也同样有效。
但是视图动画却不是!当视图动画移动组件之后,是组件的内容发生了移动,组件并没有移动,此时给组件添加的事件,并不能响应动画后的位置,只能响应原来的位置!!!
5、如果编写的是基本视图动画使用AnimationUtils.loadAnimation进行载入动画,如果编写的是属性动画使用AnimatorInflater.loadAnimator载入动画。
OK啦 大功告成!!好累~~跑步去啦 ~~
21:22:37
赞我~~~【^_^】
哦 对啦,代码地址,请猛戳这里 !!!!!
csdn地址的下载地址,在这里!