您的位置:首页 > 运维架构

Property Animation

2015-08-21 17:57 295 查看
  在Android中有三类动画,分别为View Animation(Tween Animation) , drawble Animation and property Animation . In the fast ,we should undersand defferent from View Animation and property Animation.

property Animation joined in Android 3.0, you can put the upgrade version of property Animation as View Animation. In the View Animation have many limit and disadvantage .For example , 1.当你利用动画改变了控件的位置但是它的点击局域并不会发生变化,它只是从表面上改变了形态而已。
2.它有很大的局限性,比如不能对控件的颜色属性进行动画。 所以在能用property Animation时尽量使用property Animation instead of View Animation(个人观点)。

Property Animation故名思议就是通过动画的方式改变对象的属性了,我们首先需要了解几个属性:

Duration动画的持续时间,默认300ms。

Time interpolation:时间差值,乍一看不知道是什么,但是我说LinearInterpolator、AccelerateDecelerateInterpolator,大家一定知道是干嘛的了,定义动画的变化率。

Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。

Animator sets: 动画集合,你可以定义一组动画,一起执行或者顺序执行。

Frame refresh delay:帧刷新延迟,对于你的动画,多久刷新一次帧;默认为10ms,但最终依赖系统的当前状态;基本不用管。
在property Aniamtion中有四类主要的动画执行类:ObejectAnimator ,ValueAnimator , LayoutAniamtion
,View的anim
一.ObejectAnimator
ObejectAnimator是ValueAnimator的子类。addIpdateLister是一个监听器,ObjectAnimation每动一帧都会触发这个监听。animation.getAnimatedValue()是获取ObjectAnimator动画最后一个参数的,即下列的0f;
我们可以利用updateListener来设置多种同时进行的动画。

private void objectAnimation() {
//alpha  rotationX scalaX translationX x y
//没太搞明白addUpdateListener怎么回事,只知道是在没太搞明白addUpdateListener执行完了再ofFloat里的动画
ObjectAnimator oa=ObjectAnimator.ofFloat(blueButton, "alpha", 1f, 0f);
oa.setDuration(1000);
oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
blueButton.setScaleX(2.0f);
}
});
oa.start();

//ObjectAnimator只能定义一种动画效果(也有办法多,比如AnimationSet,但是不主流),但是可以指定起始位置也可以不指定(可以有任意个参数值),可重复执行,而且由于Interpolator不能连续套用,代码要分几行写
//                ObjectAnimator.ofFloat(blueButton, "translationX", 400.0f).setDuration(1000).start();

//下面这个就是执行多种动画,利用的是AnimationSet,利用这个还可以指定顺序
ObjectAnimator animX = ObjectAnimator.ofFloat(blueButton, "x", 100f).setDuration(1000);
ObjectAnimator animY = ObjectAnimator.ofFloat(blueButton, "y", 200f).setDuration(500);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.playSequentially(animX,animY);
animSetXY.start();

//当然了还可以用PropertyValuesHolder一样可以同时执行多动画,不过貌似没AnimationSet灵活,比如我暂时没发现可以多种动画执行不同的时间
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,
0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,
0, 1f);
ObjectAnimator.ofPropertyValuesHolder(blueButton, pvhX, pvhY,pvhZ).setDuration(1000).start();
}

二.ValueAnimator

这个是一个很灵活的动画执行类,要是要写比较复杂的动画可以用这个,它有个setEvaluator方法可以自定义出我们想要的效果,颜色属性的变化就可以在这里设置(关于setEvaluator这个玩意儿还不是太清楚,后续跟进)

private void ValueAnimator() {
//        但是,下面的代码片段不会对一个对象产生实际的影响,这时因为ValueAnimator并不会直接作用在对象或属性上。
//                如过你想修改他们,最好的办法是在计算他们值的时候修改他们。你可以在ValueAnimator中通过定义监听器来在动画的持续过程中处理重要的事件,
//                例如帧更新。当你实现这些监听器的时候,你可以通过调用getAnimatedValue()来获取当前帧计算后的值。想要获取有关见提起更详细的信息,
ValueAnimator animator = ValueAnimator.ofFloat(mScreenHeight
-position[1]-150);
animator.setTarget(blueButton);
animator.setDuration(1000).start();
//监听every frame!!!!!这个监听可以监听每一帧的变化,然后执行这里的回调方法
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
blueButton.setTranslationY((Float) animation.getAnimatedValue());
}
});

//这一串是一个比较庞杂得动画,把很多元素糅合在了一起,所以写的乱七八糟的,慢慢理清楚哟
ValueAnimator animator=new ValueAnimator();
ValueAnimator animator2 = ValueAnimator.ofFloat(1.0f,0.0f).setDuration(3000);
animator2.setTarget(blueButton);
animator.setDuration(3000);
animator.setInterpolator(new LinearInterpolator());
animator.setObjectValues(new PointF(0, 0));
//后续重点跟进,这里是一个抛物线的效果
animator.setEvaluator(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
PointF point = new PointF();
// x方向200px/s ,则y方向0.5 *200* t
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}

});
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animator, animator2);
animSetXY.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
blueButton.setX(point.x);
blueButton.setY(point.y);
}

});
animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
blueButton.setAlpha((Float) animation.getAnimatedValue());
}
});
//监听动画执行状态,它可以监听多种状态,比如动画结束时,取消时等等。当然了我这里全部写出来是为了方便我做笔记,实际中只需写出自己需要得
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
ViewGroup parent = (ViewGroup) blueButton.getParent();
if (parent != null)
parent.removeView(blueButton);
}

@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
}

@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
}

@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}

@Override
public void onAnimationPause(Animator animation) {
super.onAnimationPause(animation);
}

@Override
public void onAnimationResume(Animator animation) {
super.onAnimationResume(animation);
}
});
}


三.同view Animation一样,property Animation也可以使用XML文件来定义动画

private void XmlAnimation() {
Animator anim = AnimatorInflater.loadAnimator(MainActivity.this, R.anim.scala);
//缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线,所以我决定这个横向,纵向缩小以左上角为中心点:
blueButton.setPivotX(0);
blueButton.setPivotY(0);
//显示的调用invalidate
blueButton.invalidate();
anim.setTarget(blueButton);
anim.start();
}

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together" >

<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.5" >
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.5" >
</objectAnimator>

</set>


四.布局动画(Layout Animations)



主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。
基本代码为:

[java] view
plaincopy

LayoutTransition transition = new LayoutTransition();  

    transition.setAnimator(LayoutTransition.CHANGE_APPEARING,  

            transition.getAnimator(LayoutTransition.CHANGE_APPEARING));  

    transition.setAnimator(LayoutTransition.APPEARING,  

            null);  

    transition.setAnimator(LayoutTransition.DISAPPEARING,  

            null);  

    transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,  

            null);  

    mGridLayout.setLayoutTransition(transition);  

过渡的类型一共有四种:
LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画

LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.DISAPPEARING  当一个View在ViewGroup中消失时,对此View设置的动画

LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画

LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。

注意动画到底设置在谁身上,此View还是其他View。

private void LayoutAnimation() {
// 创建一个GridLayout
mGridLayout = new GridLayout(this);
// 设置每列5个按钮
mGridLayout.setColumnCount(5);
// 添加到布局中
viewGroup.addView(mGridLayout);
//默认动画全部开启
mTransition = new LayoutTransition();
//关闭了CHANGE_DISAPPEARING的动画效果
mTransition.setAnimator(
LayoutTransition.CHANGE_DISAPPEARING,
( null));
mGridLayout.setLayoutTransition(mTransition);
}

五.View的anim

在设置简单得动画时推荐使用这种,可以减少代码量看着也整洁多了吧,而且我看google官方的Demo里很多动画也是用这种实现的,好东西

//ViewPropertyAnimator可以同时定义多种动画效果同时进行,但是都是从自身当前状态到另外一个状态
blueButton.animate().translationY(mScreenHeight-position[1]-150).scaleY(1f).scaleX(1f).alpha(2).setDuration(1000).setInterpolator


总结:
就我个人而言我,我觉得当动画简单时使用View的anim,复杂的动画使用ValueAnimation。当然了只是个人而言,每个人都有每个人的思路,只要适合自己得才是最好的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: