一:帧动画
首先帧动画的xml是在drawable文件夹下,使用标签animation-list为根标签。使用item导入各帧图片。
这里给个网址可以将gif在线分解:
gif在线分解
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true"
>
<item android:drawable="@drawable/frame-01" android:duration="100"/>
<item android:drawable="@drawable/frame-02" android:duration="100"/>
<item android:drawable="@drawable/frame-03" android:duration="100"/>
<item android:drawable="@drawable/frame-04" android:duration="100"/>
<item android:drawable="@drawable/frame-05" android:duration="100"/>
<item android:drawable="@drawable/frame-06" android:duration="100"/>
<item android:drawable="@drawable/frame-07" android:duration="100"/>
<item android:drawable="@drawable/frame-08" android:duration="100"/>
</animation-list>
代码中调用十分简单,直接设置imageview的imageresource。
binding.ivAnim.setImageResource(R.drawable.my_frame_anim);
animationDrawable= (AnimationDrawable) binding.ivAnim.getDrawable();
这种方式无需在调用start方法启动动画。
第二种方式:
animationDrawable= (AnimationDrawable) getResources().getDrawable(R.drawable.my_frame_anim);
binding.ivAnim.setBackground(animationDrawable);
这种方式需要手动调用animationDrawable.start()方法。
public void onStartAnim(){
if (animationDrawable!=null&&!animationDrawable.isRunning()){
animationDrawable.start();
}
}
public void onEndAnim(){
if (animationDrawable!=null&&animationDrawable.isRunning()) {
animationDrawable.stop();
}
}
二:补间动画
补间动画主要涉及五部分的内容:
1:平移(translate)
2:旋转(scale)
3:缩放(rotate)
4:透明度(alpha)
5:组合(animationSet)
首先,补间动画的xml布局是放在anim文件夹下,这点与帧动画不同。
2.1平移动画
1:xml中实现
xml布局如下:在这里插入代码片
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="200"
android:toYDelta="200"
android:duration="2000"
>
</translate>
怎么获取animation动画呢,使用AnimationUtils类,后面我们会详细讲到这个类,这里我们就简单先看下使用方法:
这里我们使用loadAnimation这个方法获取xml中的动画。
Animation translateAnimation= AnimationUtils.loadAnimation(this,R.anim.tween_translate_anim);
binding.ivAnim.startAnimation(translateAnimation);
具体效果:
1:java中实现
不需要xml文件,直接在java中怎么写呢?
这里我们通过使用translateAnimation来创建动画对象,
可以看到平移动画有三种构造方法。
这里我们使用第二种,
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
mFromXValue = fromXDelta;
mToXValue = toXDelta;
mFromYValue = fromYDelta;
mToYValue = toYDelta;
mFromXType = ABSOLUTE;
mToXType = ABSOLUTE;
mFromYType = ABSOLUTE;
mToYType = ABSOLUTE;
}
上面是第二种构造传入四个float值的源代码,我们可以看到,就是我们在xml中编写的fromXDelta,toXDelta,fromYDelta,toYDelta。
具体使用简单:
TranslateAnimation translateAnimation1=new TranslateAnimation(0,200,0,200);
translateAnimation1.setDuration(2000);
binding.ivAnim.startAnimation(translateAnimation1);
实现的效果跟1中的xml效果一致。
这里我们可能会发现一个问题,当我们调用平移动画,执行完后,会自动回到动画的初始位置,那么该怎样停留在平移后的位置呢?
这里涉及到的是fillbefore,fillafter和fillenabled三个属性,fillbefore默认为true,代表默认回到初始位置,fillafter代表停在动画结束的位置,优先于fillbefore,两个都设置true时,以fillafter为准。fillenabled设置为true,是否应用fillbefore,对fillafter不影响。
所以最后得到的结论是:
只要设置fillenabled=true,就可以了。
2.2旋转动画
xml实现:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="180"
android:pivotX="0"
android:pivotY="0"
android:duration="2000"
android:fillAfter="true"
>
</rotate>
pivotX和 pivotY为旋转的圆点。
fromDegrees动画开始时旋转的角度。正数为顺时针,负数为逆时针。
toDegrees动画结束时的角度。
调用:
Animation translateAnimation= AnimationUtils.loadAnimation(this,R.anim.tween_rotate_anim);
binding.ivAnim.startAnimation(translateAnimation);
java代码实现:
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
看下旋转动画参数最多的构造,我们看到多了x,y的type类型。
这里type是int值,animation中有指定,默认值是ABSOLUTE;
/**
* 指定的尺寸是绝对像素数
*/
public static final int ABSOLUTE = 0;
/**
* 指定的维度包含一个浮点数,应该乘以
*动画对象的高度或宽度
*/
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
2.3缩放动画
xml实现:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotY="50%"
android:pivotX="50%"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:toXScale="1"
android:toYScale="1"
android:duration="2000"
>
</scale>
pivotY和pivotX代表缩放的中心点,设置为0时,是以图片的左上角为起点。
fromXScale和fromYScale为起始的缩放倍数。
toXScale和toYScale代表最终的缩放倍数,大于1代表放大。
可以设置为dp等数值。
调用与平移类似,直接上代码:
Animation animation= AnimationUtils.loadAnimation(this,R.anim.tween_scale_anim);
binding.ivAnim.startAnimation(animation);
java代码实现:
先看下构造:
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotX = 0;
mPivotY = 0;
}
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
可以看到第一种默认起点为0,0。第二种可以指定pivotX和pivotY;
ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1,50,50);
scaleAnimation.setDuration(2000);
scaleAnimation.setFillAfter(true);
binding.ivAnim.startAnimation(scaleAnimation);
2.4透明度动画
xml如下:
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0" android:toAlpha="1"
android:duration="2000"
>
</alpha>
代码两种方式
public void onAlphaClicked(){
//调用xml
Animation animation= AnimationUtils.loadAnimation(this,R.anim.tween_alpha_anim);
binding.ivAnim.startAnimation(animation);
//动态创建AlphaAnimation
AlphaAnimation alphaAnimation=new AlphaAnimation(0,1);
alphaAnimation.setDuration(5000);
binding.ivAnim.startAnimation(alphaAnimation);
}
2.5组合
组合动画xml中通过set标签实现:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" >
<translate android:toYDelta="200" android:toXDelta="200" android:fromYDelta="0" android:fromXDelta="0" android:duration="4000"/>
<scale android:fromXScale="0" android:toYScale="1" android:fromYScale="0" android:toXScale="1" android:duration="4000"/>
<rotate android:fromDegrees="0" android:toDegrees="360" android:duration="1000" android:repeatMode="restart" android:repeatCount="3"/>
</set>
实现:
Animation animation= AnimationUtils.loadAnimation(this,R.anim.tween_set_anim);
binding.ivAnim.startAnimation(animation);
动态创建则需要AnimationSet 以及addAnimation方法。
public void onSetClicked(){
// Animation animation= AnimationUtils.loadAnimation(this,R.anim.tween_set_anim);
// binding.ivAnim.startAnimation(animation);
AnimationSet animationSet=new AnimationSet(true);
TranslateAnimation translateAnimation1=new TranslateAnimation(0,200,0,200);
translateAnimation1.setDuration(2000);
translateAnimation1.setFillAfter(true);
Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(2000);
rotateAnimation.setFillAfter(true);
ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1,50,50);
scaleAnimation.setDuration(2000);
scaleAnimation.setFillAfter(true);
animationSet.addAnimation(translateAnimation1);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotateAnimation);
binding.ivAnim.startAnimation(animationSet);
}
三:属性动画
属性动画主要实现类是ObjectAnimation和valueAnimation,另外属性动画也可以通过animationSet来实现组合动画。
3.1:ObjectAnimation
创建ObjectAnimation只需要通过其静态工厂类来返回对象就可以了。
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(binding.ivAnim,"translationX",200);
objectAnimator.setDuration(2000);
objectAnimator.start();