视图动画
✨执行XML中的动画
Animation animationScale = AnimationUtils.loadAnimation(this, R.anim.scale_one);
view.startAnimation(animationScale)
✨动画Animation属性
- android:duration:一次动画持续时间(单位毫秒)
- android:fillAfter:true:保持动画结束时的状态
- android:fillBefore:true:动画结束时还原到初始化状态
- android:fillEnabled:同fillBefore
- android:repeatCount:指定动画重复次数,当取值为infinite时,表示无限循环。
- android:repeatMode:用于设定重复的类型,有reverse和restart两个值。reverse表示倒序回放,restart表示重放,必须与repeatCount一起使用才能看到效果。
- android:interpolator:插值器,其实就是指定的动画效果。
1、取消动画
void cancel()
2、将控件重置到动画开始前状态
void reset()
3、设置动画监听
setAnimationListener(Animation.AnimationListener listener);
回调函数如下:
- onAnimationEnd():当动画结束时调用;
- onAnimationRepeat():当动画重复时调用;
- onAnimationStart():当动画开始时调用;
一、scale(渐变尺寸伸缩动画效果)
- android:fromXScale:动画起始时,控件在X轴方向上相对自身的缩放比例,浮点值。(1.0表示自身无变化,0.5代表缩小1倍,2.0代表放大1倍)
- android:toXScale:动画结束时,控件在X轴方向上相对自身的缩放比例,浮点值。
- android:fromYScale:动画起始时,控件在Y轴方向上相对自身的缩放比例,浮点值。
- android:toYScale:动画结束时,控件在Y轴方向上相对自身的缩放比例,浮点值。
- android:pivotX:缩放起始点X轴坐标,可以是数值、百分数、百分数p三种方式,如50、50%、50%p。如果是数值,则表示在当前视图的左上角,即原点处加上50px,作为缩放起始点X轴坐标;如果是50%,则表示在当前控件的左上角加上自己宽度的50%作为缩放起始点X轴坐标;如果是50%p,则表示在当前控件的左上角加上父控件宽度的50%作为缩放起点X轴坐标。
- android:pivotY:缩放起始点Y轴坐标,取值及含义与android:pivotX相同。
示例代码:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fromXScale="0.1"
android:fromYScale="0.1"
android:toXScale="1.5"
android:toYScale="1.5"
android:pivotX="50"
android:pivotY="50">
</scale>
代码的方式:
只要是第三个构造函数:其中pivotXType和pivotYType有以下三个取值:①、Animation.ABSOLUTE(对应的是数值),②、Animation.RELATIVE_TO_SELF(对应的是百分数),③、Animation.RELATIVE_TO_PARENT(对应的是百分数p)。
ScaleAnimation(float fromX,float toX,float fromY,float toY);
ScaleAnimation(float fromX,float toX,float fromY,float toY,float pivoteX,float pivoteY);
ScaleAnimation(float fromX,float toX,float fromY,float toY,int pivotXType,float pivotXValue,int pivotYType,float pivotYValue);
代码示例
ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATION_TO_SELF,0.5f,Animation.RELATION_TO_SELF,0.5f);
scaleAnim.setDuration(1000);
view.startAnimation(scaleAnim);
当pivotX和pivotY的数值(不是百分值)较大时,动画效果是边平移边缩放的效果。当fromXScale和fromYScale的值不是从零开始的话,pivotX和pivotY的作用就被遮盖了,可能是起始点变化比起始缩放的效果早一些执行导致的(我也很奇怪)。还有当pivotX和pivotY有值且为正值时,view会从右王左开始缩放(至于为什么我想和Matrix的具体计算有关吧,待详细了解)。
二、alpha(实现渐变透明度动画效果)
- android:fromAlpha:开始时的透明度,取值范围0.0~1.0,0.0表示全透明,1.0表示完全不透明。
- android:toAlpha:动画结束时的透明度,取值范围0.0~1.0,0.0表示全透明,1.0表示完全不透明。
示例代码:
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fromAlpha="0"
android:toAlpha="1">
</alpha>
AlphaAnimation(float fromAlpha,float toAlpha);
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
三、rotate(实现画面转移旋转动画效果)
- android:fromDegrees:动画开始旋转时的角度位置,正值代表顺时针方向的度数,负值代表逆时针方向的度数。
- android:toDegrees:动画结束时旋转到的角度位置,正值代表顺时针方向的度数,负值代表逆时针方向的度数。
-android:pivotX:旋转中心点X轴坐标,默认旋转中心点是控件坐标原点。可以是数值、百分数、百分数p三种样式,比如50、50%、50%p,具体含义同之前所讲。- android:pivotY:旋转中心点Y轴坐标,具体同上。
示例代码:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360"></rotate>
构造函数
RotateAnimation(float fromDegree,float toDegree);
RotateAnimation(float fromDegree,float toDegree,float pivotX,float
pivoY);
RotateAnimation(float fromDegree,float toDegree,int pivotXType,float pivotXValue,int pivotYType,float
pivoYValue);
代码示例:
RotateAnimation rotateAnim=new RotateAnimation(0,-650,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
四、translate(实现画面变化位置移动动画效果)
- android:fromXDelta:起始点X轴坐标,可以是数值、百分数、百分数p三种样式,作用同之前所讲。
- android:fromYDelta:起始点Y轴坐标,可以是数值、百分数、百分数p三种样式,作用同之前所讲。
- android:toXDelta:终点X轴坐标。
- android:toYDelta:终点Y轴坐标。
示例代码:
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="false"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="80"
android:toYDelta="80"></translate>
构造函数
TranslateAnimation(float fromXDelta,float toXDelta,float fromYDelta,float toYDelta);
TranslateAnimation(int fromXType,float fromXValue,int toXType,float toXValue,int fromYType,float fromYValue,int toYType,float toYValue);
代码示例
TranslateAnimation translateAnim = new TranslateAnimation(Animation.ABSOLUTE,0,Animation.ABSOLUTE,-80,Animation.ABSOLUTE,0,Animation.ABSOLUTE,-80);
五、set标签(定义动画集)
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<scale
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" />
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="720" />
</set>
构造函数:其中shareInterpolator 参数的取值有true和false。当为true时,用于在AnimationSet类中定义一个插值器(Interpolator),其下面的所有动画共用该插值器;当为false时,则其下的动画定义各自的插值器。
AnimationSet(Context context , AttributeSet attrs);
AnimationSet(boolean shareInterpolator);
示例代码:
Animation alphaAnim = new AlphaAnimation(1.0f,1.0f);
Animation scalAnim=new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATION_TO_SELF,0.5f,Animation.RELATION_TO_SELF,0.5f);
Animation rotateAnim=new RotateAnimation(0,720,Animation.RELATION_TO_SELF,0.5f,Animation.RELATION_TO_SELF,0.5f);
AnimationSet setAnim = new AnimationSet(true);
setAnim.addAnimation(alphaAnim);
setAnim.addAnimation(scalAnim);
setAnim.addAnimation(rotateAnim);
setAnim.setDuration(3000);
setAnim.setFillAfter(true);
view.startAnimation(setAnim);
注意:在set标签中设置repeateCount属性是无效的,必须对每个动画单独设置才有作用。
逐帧动画
逐帧动画就是一帧挨着一帧的播放图片,就像放电影一样,既可以通过XML代码实现也可以通过Java代码实现。
一、XML实现
1、定义xml动画文件
将xml定义在/res下的anim或drawable目录中,代码如下:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@mipmap/spinner_0"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_1"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_2"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_3"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_4"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_5"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_6"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_7"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_8"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_9"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_10"
android:duration="60" />
<item
android:drawable="@mipmap/spinner_11"
android:duration="60" />
</animation-list>
- 元素是必须的,并且必须作为根元素,可以包含一个或多个元素;
- android:oneshot如果为true,那么动画只执行一次;如果定义为false,则一直循环。
- android:drawable:指定此帧动画对应的图片资源。
- android:duration:代表此帧动画持续的时间,是一个整数,单位毫秒。
2、设置ImageView
给ImageView设置动画资源,可以通过android:src 实现,也可以通过android:background实现。
3、AnimationDrawable开始动画
最后在代码中开始动画。代码展示:
//通过android:src方式设置后的获取方式
AnimationDrawable anim =(AnimationDrawable) image.getDrawable();
//通过android:background方式设置后的获取方式
AnimationDrawable anim =(AnimationDrawable) image.getBackground();
anim.start();
3、AnimationDrawable类
- void start():开始播放逐帧动画。
- void stop():停止播放逐帧动画。
- int getDuration(int index):得到指定index的帧的持续时间。
- Drawable getFrame(int index):得到指定index的帧所对应的Drawable对象。
- int getNumberOfFrames():得到当前所有帧数量。
- boolean isRunning():判断当前AnimationDrawable是否正在播放。
- void setOneShot(boolean oneShot):设置AnimationDrawable是否执行一次,true代表执行一次,false代表循环执行。
- boolean isOneShot():判断当前AnimationDrawable是否执行一次。
- void addFrame(Drawable frame,int duration):为AnimationDrawable添加1帧,并设置持续时间。
二、代码实现
代码实现:
final AnimationDrawable anim = new AnimationDrawable();
for(int i=1;i<14;i++){
int id=getResources().getIdentifier("spinner_"+i,"mipmap",getPackageName());
Drawable drawable = getResources().getDrawable(id);
anim.addFrame(drawable,60);
}
anim.setOneShot(false);
image.setBackgroundDrawable(anim);
anim.start();
这段代码的难点是通过文件名拿到文件:
int getIdentifier(String name , String defType , String defPackage);
- String name: 所要查找资源ID的资源名称。
- String defType:资源所在的文件类型。
- String defPackage: 应用包名。