认识属性动画

传统动画Animation平移方法的实现
TranslateAnimation animation = new TranslateAnimation(x轴初始位置,x轴终止位置,y轴初始位置,y轴终止位置);
animation.setDuration(1000);//设置持续时间,ms单位
animation.setFillAfter(true);//设置动画结束后状态,true为保持最终状态

imageView.startAnimation(animation);//为控件添加要执行的动画

传统动画的局限性,只是重绘了动画,改变了显示位置,但是真正的响应位置没有发生任何改变,并不适合做具有交互的动画效果
传统动画框架的局限性:只是重绘了View,但是View原来相应事件的位置并没有改变,这样就会使得View在动画结束后,点击View没有相应,而点击View原来的位置才有响应,这就是一个很诡异的事情。

属性动画Animator与传统动画Animation

package com.example.animationtest;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.animation.TranslateAnimation;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View view){Toast.makeText(this, "click", Toast.LENGTH_SHORT).show();}public void move(View view){TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);animation.setDuration(2000);animation.setFillAfter(true);ImageView imageView = (ImageView) findViewById(R.id.imageView1);imageView.startAnimation(animation);}}

ObjectAnimator

一、ObjectAnimator属性动画
1.ObjectAnimator.ofFloat(view,”“,float,float).setDuration(1000).start();
第二个参数:
translationX、translationY偏移量
rotation旋转
X、Y偏移至
2.同时作用三个属性动画
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat(“rotation”,0,360f);
ObjectAnimator.ofPropertyValuesHolder(view,p1,p2,p3).setDuration(1000).start();

二、AnimatorSet
1.同时作用三个属性动画
ObjectAnimator animator1 = ObjectAnimator.ofFloat(view,”rotation”,0,360F);
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1,animator2,animator3);
set.start();
2.顺次播放动画
set.playSequentially(animator1,animator2,animator3);
3.组合动画
set.play(animator2).with(animator3);
set.play(animator1).after(animator2);
动画二和动画三同时播放,结束后播放动画一
Animator同样支持AnimatorSet,增加动画组合的多样性
playSequentially:按顺序进行动画的播放
playTogether:一起执行所选的动画效果
还可以进行属性集合的详细控制
set.play(动画2).with(动画3);
set.play(动画1).after(动画2);
属性动画平移的实现方法
ObjectAnimatior.ofFloat(imageView,”translationX”,0F,200f).setDuration(1000).start();
//ofFloat方法(要操作的对象,”要操作的元素”,变化范围,变化范围).设置持续时间.开始执行
要操作的元素只要包含get和set方法都可以使用属性动画,例如
translationX/translationY:X/Y轴的偏移量
X/Y:X/Y的最终量
rotation:旋转,从0度开始
ObjectAnimatior.ofFloat()方法实现的动画是同时进行的,同时操作多个属性的动画可以使用ofPropertyValuesHolder方法
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat(“rotation”,0,360F);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat(“translationX”,0,360F);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat(“translationY”,0,360F);
ObjectAnimatior.ofPropertyValuesHolder(imageView,p1,p2,p3).setDuration(1000).start();
1.ObjectAnimation.ofFloat(动作对象,String类型动作属性,float类型动作数值);
动作属性:”translationX”,”X”,”rotation”
2.多个属性动画可以同时进行,为了优化动作属性可以用以下方法:
PropertyValuesHolder p1=PropertyValuesHolder.ofFloat(“rotation”,0,360f);
ObjectAnimator.ofPropertyValuesHolder(对象, p1,p2,p3).setDuration(1000).start();
3.用set方法:
ObjectAnimator animator1=ObjectAnimator.ofFloat(对象,”属性名”,Values);
AnimatorSet set=new AnimatorSet();
set.playTogether(animator1,animator2,animator3);同时运行
set.playSequentially(animator1,animator2,animator3);连续运行
set.play(animator2).with(animator3);同时进行
set.play(animator1).after(animator3);animator1在animator3后运行
Animation平移动画 耗CPU Google提供了很多例子
TranslateAnimation animation=new TranslateAnimation(x0,x1,y0,y1)
animation.setDuration(1000)设置时间
animation.setFillAfter(true)保留平移后位置
imageview.setAnimation(animation);
属性动画:监听事件也跟着一起移动了
ObjectAnimator.ofFloat(imageview,”translationX”,0F,200F).setDuration(1000).start()

只要是有get和set的属性都可以添加属性动画
—-属性动画是异步执行的,多写几行一起动 亦可传递PropertyValueHolder来保存属性的变化,然后一起传进去ObjectAnimation.ofPropertyValueHolder(imageview,p1,p2,p3)
translationX改为X就是绝对位置
—————rotation就是旋转

使用PropertyValuesHolder实现组合动画效果。PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0,360F);PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX",0,360F);PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationY",0,360F);ObjectAnimatior.ofPropertyValuesHolder(imageView,p1,p2,p3).setDuration(1000).start();·使用AnimatorSet来完成 {AnimatorSet set = new AnimatorSet();ObjectAnimator animator1 = ObjectAnimator.offloat(imageView, "rotation", 0f, 200f);ObjectAnimator animator2 = ObjectAnimator.offloat(imageView, "translationX", 0f, 200f);ObjectAnimator animator3 = ObjectAnimator.offloat(imageView, "translationY", 0f, 200f);set.playTogether(animator1,animator2,animator3); // 动画一起播放// set.playSequentially(animator1,animator2,animator3); // 顺序播放动画// 控制动画之间的播放顺序// set.play(animator2).with(animator3); // 先X和Y一起平移// set.play(animator1).after(animator3); // 平移完成之后旋转set.setDuration(1000);set.start();}

动画监听事件

分享一下个人实现的环形菜单效果,按钮是发散成圆排布的。
float y = (float) (r * Math.sin((Math.PI / 2) / (res.length - 2) * (i - 1)));
float x = (float) (r * Math.cos((Math.PI / 2) / (res.length - 2) * (i - 1)));
ObjectAnimator animator = ObjectAnimator.ofFloat(viewList.get(i), “translationY”,
0f, -y);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(viewList.get(i), “translationX”,
0f, x);
x,y是通过数学知识计算出来的,改变x,y 的正负值,菜单弹出的方向也可以改变,其他的代码和老师的相同。
动画是速度interpolator,他可以定义动画的速度变化,从而实现更加复杂的动画效果。设置interpolator的方法:
ObjectAnimator的setInterpolator()方法,参数可以传递各种各样的interpolator,比如:
objectAnimator.setInterpolator(new BounceInterpolator());
animator.addListener(new AnimatorListenerAdapter); //只要重写一个事件
animator.setStartDelay(x);//依次弹出x为间隔毫秒
setInterpolator(new XXX);//设置动画的速度变换
alpha 透明度
rotation z轴旋转
rotationX x轴旋转
rotationY y轴旋转
translationX x水平偏移
translationY y水平偏移
ScaleX x轴缩放
ScaleY y轴缩放
AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速

AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速

AnticipateInterpolator 开始的时候向后然后向前甩

AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值

BounceInterpolator 动画结束的时候弹起

CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线

DecelerateInterpolator 在动画开始的地方快然后慢

LinearInterpolator 以常量速率改变

OvershootInterpolator 向前甩一定值后再回到原来位置
alpha 透明度
rotation z轴旋转
rotationX x轴旋转
rotationY y轴旋转
translationX x水平偏移
translationY y水平偏移
ScaleX x轴缩放
ScaleY y轴缩放

Tips:1.ObjectAnimator.ofFloat(view,"alpha",0F,1F);一、给Animator添加监听1.animator.addListener(new Animator.AnimatorListener(){...});2.animator.addListener(new AnimatorListenerAdapter(){...});不需重写所有事件方法二、例子1.animator.setStartDelay(300);动画延时0.3s2.animator.setInterpolator(new BounceInterpolator());差值器(弹性)ObjectAnimator animator = ObjectAnimator.ofFloat(view,"alpha",0,1f).setDuration(1000);animator.addListener(new Animator.AnimatorListener() {public void onAnimationStart(Animator animation) {}public void onAnimationEnd(Animator animation) {}public void onAnimationCancel(Animator animation) {}public void onAnimationRepeat(Animator animation) {}});//选择监听事件animator.addListener(new AnimatorListenerAdapter(){});//差值器(均速度,加速度,抛物线)内置九种差值器animator,setInterpolator(new BounceInterpolator());
public class ListenForAnEvent extends Activity implements OnClickListener {    private int[] ids = {R.id.a, R.id.b, R.id.c, R.id.d, R.id.e, R.id.f, R.id.g, R.id.h };    private List<ImageView> imageViewList = new ArrayList<ImageView>();    private boolean flag = false;    private int r = 250;    /* * (非 Javadoc) Description: * @see android.app.Activity#onCreate(android.os.Bundle) */    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_listen_event);        for (int i = 0; i < ids.length; i++) {            ImageView imageView = (ImageView) findViewById(ids[i]);            imageViewList.add(imageView);            imageView.setOnClickListener(this);        }    }    /* * (非 Javadoc) Description: * @see android.view.View.OnClickListener#onClick(android.view.View) */    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.a:            if (!flag) {                startAnimator();            } else {                closeAnimator();            }            break;        default:            Toast.makeText(ListenForAnEvent.this, "Image=" + v, Toast.LENGTH_SHORT).show();            break;        }    }    /** * @Description (关闭动画) */    private void closeAnimator() {        for (int i = 1; i < ids.length; i++) {            float y = (float) (r * Math.sin((Math.PI / 2) / (ids.length / 2) * (i - 1)));            float x = (float) (r * Math.cos((Math.PI / 2) / (ids.length / 2) * (i - 1)));            ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", x, 0);            ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", y, 0);            AnimatorSet animator = new AnimatorSet();            animator.playTogether(animatorX, animatorY);            // ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", i * 100F, 0);            animator.setDuration(1000);            animator.setInterpolator(new BounceInterpolator());            animator.setStartDelay(i * 1000);            animator.start();            flag = false;        }    }    /** * @Description (开启动画) */    private void startAnimator() {        for (int i = 1; i < ids.length; i++) {            float y = (float) (r * Math.sin((Math.PI / 2) / (ids.length / 2) * (i - 1)));            float x = (float) (r * Math.cos((Math.PI / 2) / (ids.length / 2) * (i - 1)));            Log.d("jia", "y=" + y);            ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", 0, x);            ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0, y);            AnimatorSet animatorSet = new AnimatorSet();            animatorSet.playTogether(animatorX, animatorY);            // ObjectAnimator animatorSet = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0, i * 100F);            animatorSet.setDuration(2000);            animatorSet.setInterpolator(new OvershootInterpolator());            animatorSet.setStartDelay(i * 1000);            animatorSet.start();            flag = true;        }    }}

ValueAnimator

ObjectAnimator常用属性:
translationX、translationY ;rotation、rotationX、rotationY ;scaleX、scaleY ; X、Y ; alpha
常用方法、类:
ValueAnimator、ObjectAnimator、AnimatorUpdateListener、AnimatorListenerAdapter、PropertyValuesHolder、AnimatorSet、TypeEvalueators、Interpolators
2.ofObject()自定义
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator(){
//fraction时间因子,0~1
public Object evaluate(float fraction, PointF startValue, PointF endValue){
return null;
}
});

三、总结
1.ObjectAnimator常用属性:
translationX、translationY ;rotation、rotationX、rotationY ;scaleX、scaleY ; X、Y ; alpha
2.常用方法、类
ValueAnimator、ObjectAnimator、AnimatorUpdateListener、AnimatorListenerAdapter、PropertyValuesHolder、AnimatorSet、TypeEvalueators、Interpolators
在属性动画框架中最常用的方法和类:
ValueAnimator
ObjectAnimator
AnimatorUpdateListener
AnimatorListenerAdapter
PropertyValuesHolder
AnimatorSet
TypeEvaluators
Interpolators
一、ValueAnimator
1.ValueAnimator本身并不会作用于任何一个属性,也不会提供任何一个动画,它是一个数值发生器
2.计算属性动画中每一步的具体动画效果
3.如何产生值:
ValueAnimator会根据动画已进行的时间与其持续的总时间的比值产生一个0~1的时间因子,有了这样一个时间因子,经过相应的变换,就可以根据startValue()和endValue()来生产中间的相应值。同时,通过插值器的使用,可以进一步地控制每一个时间因子产生值的变化速率。
4.ObjectAnimator继承自ValueAnimator

二、ValueAnimator的使用
1.ofInt()
ValueAnimator animator = ValueAnimator.ofInt(0,100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener{
public void onAnimationUpdate(ValueAnimator animation){
Integer value = (Integer)animation.getAnimatedValue();
}
});
下面的例子是利用ValueAnimator实现一个Button上数字的改变。ValueAnimator是一个timing engine,他负责进行动画时候变化的中间值的计算,比如这个例子,我们就是想看在5000毫秒内,如果一个值从0变化到100,并且进行匀速变化的话是什么情况(我们没有为ValueAnimator设置Interpolator,所以默认的就是匀速变化)。通过addUpdateListener()方法我们可以监听到ValueAnimator在计算和改变值的时候每一帧数据,所以在这个监听器的回调方法中我们就可以通过getAnimatedValue()来获取每一帧的值,从而将它设置到UI上,实现我们想要的效果。所以如果我们不想要动画效果,只关心动画中各个值的变化,我们想获取这些变化的值在动画中的中间值和这些值的变化效果,我们就可以考虑使用ValueAnimator(这个类的名字也取的很贴切)。
ValueAnimator数值发生器
产生数值
ofInt(1,100)
ValueAnimator的addUpdateListener()监听获取每一步产生的数值
—————-在匿名内部类中通过getAnimatedValue()方法获得数值
自定义数值发生器:
ValueAnimator.ofObject(new TypeEvaluator<可指定泛型>(){实现evaluate(0-1的时间因子,开始,结束值)方法})
一、ValueAnimator
1.ValueAnimator本身并不会作用于任何一个属性,也不会提供任何一个动画,它是一个数值发生器
2.计算属性动画中每一步的具体动画效果
3.如何产生值:
ValueAnimator会根据动画已进行的时间与其持续的总时间的比值产生一个0~1的时间因子,有了这样一个时间因子,经过相应的变换,就可以根据startValue()和endValue()来生产中间的相应值。同时,通过插值器的使用,可以进一步地控制每一个时间因子产生值的变化速率。
4.ObjectAnimator继承自ValueAnimator

二、ValueAnimator的使用
1.ofInt()
ValueAnimator animator = ValueAnimator.ofInt(0,100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener{
public void onAnimationUpdate(ValueAnimator animation){
Integer value = (Integer)animation.getAnimatedValue();
}
});

更多相关文章

  1. [Android]使用AdapterTypeRender对不同类型的item数据到UI的渲染
  2. android获取监听SD Card状态的方法
  3. android rgb颜色设置方法及常用颜色的RGB值
  4. Android(安卓)Activity之Window的创建过程
  5. Android(安卓)7.1 WebView 实现方式选择
  6. Android中的动画--笔记
  7. Android中如何清除缓存
  8. Android动画详解之Android动画属性和实现方法(一)
  9. Android中的Drawable资源—— VectorDrawable

随机推荐

  1. SQLServer 数据库开发顶级技巧
  2. SQL 提权 常用命令
  3. sqlserver 中一些常看的指标和清除缓存的
  4. SQLServer 快速备份的十种方法
  5. sql2000 卸载后重新安装时不能安装的解决
  6. sqlserver 无法验证产品密匙的完美解决方
  7. 数据库的一些常用知识
  8. SQLServer 连接异常与解决方法小结
  9. SQLServer 通用的分区增加和删除的算法
  10. SQLServer 批量插入数据的两种方法