Android 动画大致可以分为view animation(视图动画,补间动画) ,drawable animation(帧动画),property animation(属性动画)
View Animation
视图动画只能作用于view对象,是对view的变换,有以下的四种变换
- AlphaAnimation(透明度变化)
- ScaleAnimation(缩放变化)
- TranslateAnimation(位移变化)
- RotateAnimation (旋转变化)
还有一个AnimationSet让上面的动画集合起来一起运行,都是Animation的子类
AlphaAnimation
直接alpha作为根元素
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
android:fromAlpha="0.0"
android:toAlpha="1.0"
>
</alpha>
或者用set作为根元素
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="2000"
android:fillAfter="true"
android:fromAlpha="0.0"
android:toAlpha="1.0"
/>
</set>
将xml加载到view中
alphaImageView.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha));
再或者可以直接用java new 一个AlphaAnimation出来
AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setDuration(1000);//必须设置一个大于0的数值,默认是0
alphaImageView.startAnimation(alphaAnimation);
运行的gif就不放了,用到的属性说明下,
- toAlpha 动画结束时的透明度 float (0.0 ~ 1.0,完全透明~完全不透明)
- fromAlpha 动画开始的透明度 float
- duration 动画持续时间 单位毫秒
- fillAfter 动画结束后是否保持结束后的状态 boolean true为保持
ScaleAnimation
参数介绍 :
- fromX 动画开始时X轴的缩放比例,1.0表示当前view的正常比例
- toX 动画结束时x轴的缩放比例,那么在x轴缩放的比例就是 toX - fromX
- fromY 类似
- toY 类似
- pivotX x方向上的缩放起点,默认是0
- pivotY Y方向上的缩放起点,默认是0
- pivotType 缩放起点的类型,有三种
/**
* The specified dimension is an absolute number of pixels.
* 默认是这种,相对于控件的0坐标
*/
public static final int ABSOLUTE = 0;
/**
* The specified dimension holds a float and should be multiplied by the
* height or width of the object being animated.
* 相对与自身的宽/高的百分比,1.0 == 100%
*/
public static final int RELATIVE_TO_SELF = 1;
/**
* The specified dimension holds a float and should be multiplied by the
* height or width of the parent of the object being animated.
* 相对于父控件的百分比
*/
public static final int RELATIVE_TO_PARENT = 2;
demo
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.5f, 1.0f, 1.5f);
scaleAnimation.setDuration(2000);
scaleAnimation.setFillAfter(true);
alphaImageView.startAnimation(scaleAnimation);
把构造方法加上pivot,
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.5f, 1.0f, 1.5f, 175f, 175f);
我们把缩放起点设置为175,那么它的缩放就从这个起点向两边开始缩放
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.5f, 1.0f, 1.5f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
我们把它的起点模式改为relative_to_self,pivotX 和 pivotY改为0.5,意思就是它的缩放起点变为这个view的宽高的中点,向两边放大至原来的1.5倍
* @param fromXType Specifies how fromXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
fromXType 就是用于解释解释fromCValue,其余的也是同样意思,和上面的ScaleAnimation
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 1.0f,
Animation.ABSOLUTE,0, Animation.ABSOLUTE, 0);
translateAnimation.setDuration(2000);
translateAnimation.setFillAfter(true);
alphaImageView.startAnimation(translateAnimation);
不放图了.....
RotateAnimation
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(2000);
rotateAnimation.setFillAfter(true);
alphaImageView.startAnimation(rotateAnimation);
围绕图片中心转一圈,
AnimationSet
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fillAfter="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
<scale
android:fromXScale="0.1"
android:fromYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
<translate
android:fromXDelta="-50%p"
android:toXDelta="0"/>
</set>
这里说一下50% 和 -50%p ,单纯只是%就是基于view本身,也就Animation.RELATIVE_TO_SELF,而%p就是基于view的parent,也就是Animation.RELATIVE_TO_PARENT.
图中的view宽度为60px,父view为100px,左右两边平分,各为20px,针对view的动画
<translate
android:fromXDelta="-50%p"
android:toXDelta="0"/>
这个的意思就是:
view动画的开始位置是:view在图中的位置向左移动距离(0.5 * 100 = 50 ,为什么是左,-50%p)px,就是view在图片当前的位置向左移动50px就开始动画,这个移动的过程当然是看不到的,并且这不是view真正的移动,这里只是文字表述,view其实一直不改变它所在的位置。
结束位置就是view当前所在的位置,也就是view的左边距离父的左边20px
Interpolator
通过定义Interpolator可以改变动画的速率,比如加速,减速,匀速等,Android定义了一系列的interpolator
accelerate decelerate interpolator
动画开始和动画结束的时候速度较慢,中间的速度较快。默认的插值器就是这个,在xml中的引用
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
accelerate interpolator
动画从开始到结束的过程中一直加速,有个参数factor,就是设置速率的变化的,factor默认是1.0,factor的值越大 ,开始的速度就会变得更加慢,结束的速度更加快。
ValueAnimator
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(2000);//设置动画时间,默认是300
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());//设置插值器,默认也是这个
valueAnimator.setFloatValues(0, 200);//设置开始值和结束值
//监听属性值的改变
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float tem = (float) animation.getAnimatedValue();
Log.d(TAG, "onAnimationUpdate: " + tem);
view.setTranslationY(tem);
}
});
//开始动画
valueAnimator.start();
第一个参数就是动画应用在哪个对象,第二个参数就是设置这个动画改变的属性,第三个可变参数,写一个就是属性的开始值,两个就是一个开始值一个结束值。这里改变的属性值必须有setXxx方法,因为是通过反射调用设置这个属性的,还有就是这这个方法中必须包含对这个view 的重绘的方法,view.postInvalidate(); / view.invalidate();否则你设置了这个属性也不能在界面上马上看到效果,也就没有动画可言。
TypeEvaluate
自定义TypeEvaluate
实现抛物线,x方向是100px/s,y方向的加速度是200px/s*s
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
PointF pointF = new PointF();
//fuction = t /duration
pointF.x = 100 * 2 * fraction;
pointF.y = 0.5f * 200 * 2 * fraction * 2 * fraction;
return pointF;
}
}, new PointF(0, 0));
animator.setDuration(2000);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF p = (PointF) animation.getAnimatedValue();
view.setTranslationX(p.x);
view.setTranslationY(p.y);
}
});
animator.start();
xml实现
objectAnimator
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="y"
android:valueFrom="0.0"
android:valueTo="300.0"
android:valueType="floatType">
</objectAnimator>
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.value_animator);
animator.setTarget(view);
animator.start();
animatorSet
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="0.2"
android:valueType="floatType"
/>
<objectAnimator
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="scaleY"
android:valueFrom="1.0"
android:valueTo="0.2"
android:valueType="floatType"
/>
<objectAnimator
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="rotationX"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"
/>
</set>
java
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.value_animator_set);
set.setTarget(view);
set.start();
set中的一个参数就是ordering,顺序可以选择together(同一时间所有动画一起开始),也可以选择sequentially(按set中的顺序顺序一个个开始)。
纯java animatorSet
AnimatorSet set= new AnimatorSet();
set.play(AnimatorInflater.loadAnimator(this, R.animator.value_animator)).
with(new ObjectAnimator().setDuration(2000).ofFloat(view, "x", 0, 200));
set.setTarget(view);
set.setDuration(2000);
set.start();
https://github.com/lijinxiong/note/blob/master/Android/%E5%8A%A8%E7%94%BB.md
网友评论