视图动画(补间动画+逐帧动画)

视图动画

✨执行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: 应用包名。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容