两种动画使用方法记录
1、ObjectAnimator
。。。。。ObjectAnimator:直接动画所给的对象,他会调用对象对应属性的get/set方法吧属性的值设置给对象的属性,直接实现动画效果。
有四大框架(使用方法其实差不多)
- alpha(透明度动画)
- scaleX/scaleY(缩放动画)
- translateX/translateY(平移动画)
- rotation(旋转动画)
private void iniAnimation(){
// 透明度动画
ObjectAnimator.ofFloat(mAlphaImage, "alpha", 1, 0, 1)
.setDuration(4000)
.start();
// 缩放
final AnimatorSet animatorSet = new AnimatorSet();
mScaleImage.setPivotX(mScaleImage.getWidth()+250);
mScaleImage.setPivotY(mScaleImage.getHeight()+250);
animatorSet.playTogether(
ObjectAnimator.ofFloat(mScaleImage, "scaleX", 1, 0)
.setDuration(2000),
ObjectAnimator.ofFloat(mScaleImage, "scaleY", 1, 0)
.setDuration(2000)
);
animatorSet.start();
// 平移 translation
final AnimatorSet translationAnimatorSet = new AnimatorSet();
translationAnimatorSet.playTogether(
ObjectAnimator.ofFloat(mTranslationImage, "translationX", 20, 100)
.setDuration(2000),
ObjectAnimator.ofFloat(mTranslationImage, "translationY", 20,100)
.setDuration(2000)
);
translationAnimatorSet.start();
// 利用 ObjectAnimator 实现旋转动画
final AnimatorSet rotateAnimationSet = new AnimatorSet();
rotateAnimationSet.playTogether(
ObjectAnimator.ofFloat(mRotationImage, "rotation",0, 360)
.setDuration(2000)
);
rotateAnimationSet.start();
}
一、这个是从别的博客借鉴的,已经非常详细了,照搬即可。
统一步骤:创建AnimatorSet对象;在playtogether方法中设置参数,以平移为例,ofFloat方法中,设置view对象名,动画效果,起始位置,结束位置(如果我添加了touch事件,结束位置每次都不一样,现在我还不知道是为什么);设置动画持续时间;最后开始动画。
二、原理讲解:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);
TextView控件有rotation这个属性吗?没有,不光TextView没有,连它的父类View中也没有这个属性。那它是怎么来改变这个值的呢?其实,ObjectAnimator做动画,并不是根据控件xml中的属性来改变的,而是通过指定属性所对应的set方法来改变的。比如,我们上面指定的改变rotation的属性值,ObjectAnimator在做动画时就会到指定控件(TextView)中去找对应的setRotation()方法来改变控件中对应的值。同样的道理,当我们在最开始的示例代码中,指定改变”alpha”属性值的时候,ObjectAnimator也会到TextView中去找对应的setAlpha()方法。
三、我在项目中利用了 getY() 获得自定义view距屏幕顶的距离,这里贴一张图片
四、注:
- ofFloat()方法里面的数字参数,单位是px。
- ofFloat()方法里面的位置坐标,是以view为原点(0,0)判定的。
五、自定义View支持Padding属性,但是在xml布局文件中设置不会生效,只能在自定义View类中,重写onDraw方法时设置。
六、获取屏幕宽高的方法:
private void getWidthAndHeight() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
width = dm.widthPixels;
height = dm.heightPixels;
System.err.println("yidong -- width = " + width);
System.err.println("yidong -- height = " + height);
}
七、设置动画过程监听器:
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
System.err.println("yidong -- onAnimationStart");
}
@Override
public void onAnimationEnd(Animator animation) {
System.err.println("yidong -- onAnimationEnd");
}
@Override
public void onAnimationCancel(Animator animation) {
System.err.println("yidong -- onAnimationCancel");
}
@Override
public void onAnimationRepeat(Animator animation) {
System.err.println("yidong -- onAnimationRepeat");
}
});
2、ValueAnimator
。。。。。ValueAnimator是ObjectAnimator的父类,我们给ValueAnimator传递两个值(起始和终止)ValueAnimator 并不会自动去执行什么,而是会通过 addUpdateListener 的监听方法,在时间插值器的 作用下,有序的返回一连串数值,然后我们就可以通过这些数值,对控件进行设置。
。。。。。ValueAnimator:这个动画是针对属性的值进行动画的 ,不会对UI造成改变,不能直接实现动画效果。需要通过对动画的监听去做一些操作,在监听中将这个值设置给对应的属性,对应的属性才会改变。
。。。。。以平移动画为例:
ValueAnimator valueAnimator = ValueAnimator.ofFloat(lastY, infViewEndPosition);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Log.e(TAG, "float=" + valueAnimator.getAnimatedValue());
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) infView.getLayoutParams();
layoutParams.topMargin = Math.round((Float) valueAnimator.getAnimatedValue());
infView.setLayoutParams(layoutParams);
}
});
valueAnimator.setDuration(500);
valueAnimator.start();
先创建ValueAnimator对象,利用ofFloat方法赋值起始点和终止点(如果是ofObject方法,似乎可以把x,y全都赋值了,现在这样好像只能赋值xy中的一个),然后重写addUpListener中的onAnimationUpdate方法,我在里面添加了移动方法,设定动画持续时间,开始动画。