在项目开发中,根据需求会有一些动画的效果,在android3.0之前的就有补间动画(Tween Animation)和帧动画(Frame Animation),但是实现的效果有限,android3.0之后就出现了属性动画(Property Animation),属性动画更改的是View实际的属性,所以不会影响其在动画执行后所在位置的正常使用。
属性动画常用api:
ObjectAnimator :对象动画执行类。
PropertyValuesHolder : 属性存储器,为两个执行类提供更新多个属性的功能。
AnimatorListener :动画执行监听,在动画开始、重复、结束、取消时进行回调。
Keyframe :为 PropertyValuesHolder提供多个关键帧的操作值。
AnimatorSet :一组动画的执行集合类:设置执行的先后顺序,时间等。
TimeInterpolator :时间插值,用于控制动画执行过程。
ValueAnimator :值动画执行类,常配合AnimatorUpdateListener使用。
AnimatorUpdateListener :动画更新监听。
TypeEvaluator :类型估值,用于设置复杂的动画操作属性的值。
属性动画插值器:
AccelerateDecelerateInterpolator :加速减速插值器
AccelerateInterpolator :加速插值器
AnticipateInterpolator :回荡秋千插值器
BounceInterpolator :弹跳插值器
CycleInterpolator :正弦周期变化插值器
DecelerateInterpolator :减速插值器
AnticipateOvershootInterpolator :开始的时候向后然后向前甩一定值后返回最后的值
OvershootInterpolator:向前甩一定值后再回到原来位置
属性动画的设置:
1)translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。
3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
5)x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
6)aplha:透明度,1是完全不透明,0是完全透明。
translationX 和 translationY:
private void startAnimationVaule(View view){
//X平移动画
ObjectAnimator oa = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f);
oa.setDuration(500);
oa.start();
//Y平移动画
ObjectAnimator ob=ObjectAnimator.ofFloat(view,"translationY",0f,300f);
ob.setDuration(500);
ob.start();
}
如果想添加插值器,在start之前设置相应的插值器就可以了;
rotationX 和 rotationY:
//X翻转动画
ObjectAnimator oc=ObjectAnimator.ofFloat(view,"rotationX",0f,360f);
oc.setDuration(500);
oc.start();
scaleX 和 scaleY:
//X缩放
ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 1f, 0.5f);
scaleX.setDuration(500);
scaleX.start();
aplha:
//透明度动画
ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "alpha", 1f, 0.5f);
scaleX.setDuration(500);
scaleX.start();
在项目开发中可能不只是单个属性动画的时候,可能会涉及到多个动画的同时使用,对于多个动画同时执行的方式有很多种:
方式一:
private void startMoreAnimationSecond(View view){
//如果没有这个属性的时候,就默认valueanimator
ObjectAnimator haha = ObjectAnimator.ofFloat(view, "haha", 0f, 100f);
haha.setDuration(300);
//设置监听动画
haha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//动画在执行的过程中,不断的调用此方法
Float animatedValue = (Float) animation.getAnimatedValue();
//X翻转
iv.setScaleX(0.5f+animatedValue/200);
//Y翻转
iv.setScaleY(0.5f+animatedValue/200);
}
});
//开启动画
haha.start();
}
方式二:
private void startMoreAnimationThrid(View view){
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 200f);
valueAnimator.setDuration(200);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float animatedValue = (Float) animation.getAnimatedValue();
iv.setScaleX(0.5f+animatedValue/200);
iv.setScaleY(0.5f+animatedValue/200);
}
});
valueAnimator.start();
}
方式三:
private void startMoreAnimationFour(View view){
//透明度动画
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0.7f, 1f);
//X缩放
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.7f, 1f);
//Y缩放
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.7f, 1f);
//X平移
PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 0f, 300f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(iv, alpha, scaleX, scaleY, translationX);
objectAnimator.setDuration(1000);
objectAnimator.start();
}
方式四:
private void startMoreAnimationFive(View view){
//透明度动画
ObjectAnimator alpha = ObjectAnimator.ofFloat(iv, "alpha", 1f, 0.7f, 1f);
//X缩放
ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 1f, 0.7f, 1f);
//Y缩放
ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 1f, 0.7f, 1f);
//动画集合
AnimatorSet set=new AnimatorSet();
set.setDuration(500);
//同时执行动画
// set.playTogether(alpha,scaleX,scaleY);
//依次执行动画
set.playSequentially(alpha,scaleX,scaleY);
set.start();
}
属性动画仿淘宝产品(IOS)详情动画效果:
这个效果涉及到几个属性动画的同时使用和执行;
第一个view:翻转动画、透明度动画、缩放动画、平移动画
第二个view:平移动画
private void setAnimator(final boolean isFrist){
float fristValue=0;
float secondValue=0;
//frist 1 翻转动画 2透明度动画 3缩放动画 4平移动画
//翻转
if(isFrist){
fristValue= 0f;
secondValue=25f;
}else{
fristValue= 0f;
secondValue=25f;
}
ObjectAnimator rotationX = ObjectAnimator.ofFloat(frist, "rotationX", fristValue, secondValue);
rotationX.setDuration(300);
//透明度动画
if(isFrist){
fristValue= 1f;
secondValue=0.5f;
}else{
fristValue= 0.5f;
secondValue=1f;
}
ObjectAnimator alpha = ObjectAnimator.ofFloat(frist, "alpha", fristValue, secondValue);
alpha.setDuration(200);
//缩放动画
if(isFrist){
fristValue= 1f;
secondValue=0.8f;
}else{
fristValue= 0.8f;
secondValue=1f;
}
ObjectAnimator scaleX = ObjectAnimator.ofFloat(frist, "scaleX", fristValue, secondValue);
scaleX.setDuration(300);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(frist, "scaleY", fristValue, secondValue);
scaleY.setDuration(300);
//改正向旋转设置监听,执行完毕后再执行反向旋转
if(isFrist){
fristValue= 25f;
secondValue=0f;
}else{
fristValue= 25f;
secondValue=0f;
}
ObjectAnimator rotationX1 = ObjectAnimator.ofFloat(frist, "rotationX", fristValue, secondValue);
rotationX1.setDuration(200);
//延时执行动画
rotationX1.setStartDelay(200);
if(isFrist){
fristValue= 0f;
secondValue=-0.1f * frist.getHeight();
}else{
fristValue= -0.1f * frist.getHeight();
secondValue=0f;
}
//由于缩放造成了离顶部有一段距离,需要平移上去
ObjectAnimator translationY = ObjectAnimator.ofFloat(frist, "translationY", fristValue, secondValue);
translationY.setDuration(200);
//第二个view执行平移动画---往上平移
if(isFrist){
fristValue= second.getHeight();
secondValue=0f;
}else{
fristValue= 0f;
secondValue=second.getHeight();
}
ObjectAnimator translationY1 = ObjectAnimator.ofFloat(second, "translationY", fristValue, secondValue);
translationY1.setDuration(200);
translationY1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
//动画开始的时候会回调
second.setVisibility(View.VISIBLE);
if(isFrist){
bt.setClickable(false);
}
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//动画结束的时候会回调
if(!isFrist){
bt.setClickable(true);
}
}
});
//将动画放到动画集合中
AnimatorSet set=new AnimatorSet();
set.playTogether(rotationX,alpha,scaleX,scaleY,rotationX1,translationY,translationY1);
//开启动画
set.start();
}
在对应的点击事件那里调用就可以了;
public void startFirstAnimation(View view){
//产品详情处点击事件
setAnimator(true);
}
public void startSecondAnimation(View view){
setAnimator(false);
}