android 同根动画_android 动画系列 (1) - tween 动画(view动画)

这是我这个系列的目录,有兴趣的可以看下: android 动画系列 - 目录

tween 动画早些时候我们也叫补间动画(我也不知道为啥),现在也有叫 view 动画的。tween动画是2.X 时代的产物,因为效果不理想,4.X 时代推出了动画的升级版 属性动画。给我的感觉 属性动画就是tween动画的升级版,属性动画就是替换 tween 的,现在来看也的确时这样的,大部分的场景我们现在都是使用属性动画的,只有一些较老的 api 中会使用 tween 动画。

既然tween 动画和属性动画是承前启后的关系,那么2者理所应当的在使用是很相似,参数也很相似,这里有些参数我们在 tween 动画这节中介绍过后,就不再属性动画中介绍了。

tween 动画实现的的4种动画效果:

平移动画 TranslateAnimation

缩放动画 ScaleAnimation

旋转动画 RotateAnimation

透明度动画 AlphaAnimation

对于tween 动画,目前使用的机会并不是很多了,使用时一般都是使用 定义好的动画xml文件,推荐大伙这么做。

xml 文件定义的位置:/res/anim目录下

通用 xml 属性介绍

Snip20170722_18.png

上面这些都是我在定义 xml tween 动画时会用到的属性,上面的表里基本上很全了,解释的也很到位

android:startOffset="100" 注意这个 startOffset 参数,这是动画执行的延迟时间,tween 动画使用 startOffset 属性,属性动画使用 delay 属性,这是 tween 和属性动画在定义时需要注意的,话说使用同一个单词不好嘛,非要用2个...

tween 动画数值体系和坐标体系

先来说一下坐标体系,这个属于大家应该熟记的,也是能猜测出来的,tween 动画时作用与 view 之上的,那么 tween 的坐标体系也是以目标 view 的坐标为参考的。具体来说就是以 目标 view 的左上角为坐标原点。明白这点我么再往下面看。

细心的朋友应该会发现,我们在设置 tween 动画参数时出现过3种不同的写法:30,30%,30%p。这3种写法有其不同的含义,我们来仔细看一下。

参数数值体系,这里以平移来举例:

30,以目标 view 的左上角为原点,让 view 向右移动30px

30%,以目标 view 左上角为原点,让 view 向右移动 view 宽度的30%

30%p,以目标 view 左上角为原点,让 view 向右移动父容器宽度的30%

了解了 tween 动画的坐标系,再来看动画的数值参数,移动的方向大伙都应该知道了,那么具体上面3种写法就是偏移量的不同了,30是 px 像素,30%是以 view 自身宽高算的,30%p 是以 view 的父容器的宽高算的

缩放,旋转动画的中心点大伙应该都恩那个猜出来是view 的左上角了吧,我们学习很重要的一点就是举一反三,看破一点,总揽全局。

translate位移动画

效果图:添加了自动返回的代码

ezgif.com-video-to-gif.gif

tween 动画我们可以使用 xml 来定义,也可以自己撸代码

xml 定义:

android:duration="600"

android:fromXDelta="0"

android:fromYDelta="0"

android:repeatCount="1"

android:repeatMode="reverse"

android:toXDelta="100"

android:toYDelta="100"

/>

我们定义完 xml 文件后,不就是完事了,我们还得把动画绑定给一个 view ,并开始才能启动动画效果

Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.tran1); // R.anim.tran1是我们定义号的动画 xml

imageTest.startAnimation(animation1); // imageTest是要显示动画的 view

这样我们就可以使用tween 动画了,当然这是最简单的使用方式了,注意看所有的 tween 动画的都实现了 Animation接口。

对于 xml 的定义,虽然上面介绍过参数的含义了,我在这里还是说一下的好,便于理解啊。

duration 是动画执行时间,我们要是不写的话,默认是300ms,在 xml 中,时间都是以 ms 为单位的

fromXDelta/fromYDelta 是动画开始时 view x/y 轴的偏移量,一般我们都写0,

toXDelta/toYDelta 是位移动画在 view x/y 轴上最终的偏移量,也可以理解为我们想让 view 到达的新位置,也可以理解为动画的执行幅度

repeatMode 是动画的重复模式,有2个模式:reverse/restart。 reverse是回复原状,restart是重复执行。

repeatCount 是动画的重复次数

Animator.setRepeatCount(ValueAnimator.INFINITE) 也可以实现重复执行的效果

fillAfter 动画执行后是否保留 view 所在的新位置, true 保留,false 回归初始位置

fillBefore 和fillAfter不一样,不论是 true 还是 false,都会回归初始位置

这里注意 repeatMode/repeatCount ,这2个参数必须都写才有意思,只写一个是不成立的,我在下面会专门说下重复模式和重复次数的问题,这个和大家想象有些不一样,我可是专门都跑了一遍才清楚的。

java 代码定义:

TranslateAnimation translateAnimation = new TranslateAnimation(0, 100, 0, 100);

translateAnimation.setDuration(600);

translateAnimation.setRepeatMode(TranslateAnimation.REVERSE);

translateAnimation.setRepeatCount(1);

imageTest.startAnimation(translateAnimation);

我们也是可以 new 一个 tween 动画的直接实现类出来的,这里使用的是 TranslateAnimation 最简单的构造函数

上面说了 tween 动画有3种参数形式:30,30%,30%p,这里我们就来试试看啊,不试试怎么能清楚尼...

让我们来看看30%,上面使用的是100px,现在我们来看看100%是啥样子的,看看和猜测的是不是一样,向右位移自身尺寸的100%后,应该是靠近右侧边缘了

android:duration="600"

android:fillAfter="true"

android:fromXDelta="0"

android:fromYDelta="0"

android:toXDelta="100%"

android:toYDelta="100%"

/>

效果图:

ezgif.com-video-to-gif.gif

啊,和我们预计的一样,向右位移了 view 自身的宽高值,和明显的能够看出来

接下来让我们看看 30%p,为了效果明显,数值这里使用了 80%p

android:duration="600"

android:fillAfter="true"

android:fromXDelta="0"

android:fromYDelta="0"

android:toXDelta="80%p"

android:toYDelta="80%p"

/>

效果图:

ezgif.com-video-to-gif.gif

哈哈,大伙注意啊,这里 view 的父控件可是根视图节点了,所以向右偏移量很大,直接出去了,大伙没有没想过要是给这个 view 添加一个父控件,会怎么样呢...让我们来看看:

view 的大小是100dp,给view 添加一个200dp 的外壳,蓝色背景

xml布局:

android:layout_width="200dp"

android:layout_height="200dp"

android:layout_centerHorizontal="true"

android:background="@color/colorPrimary">

android:id="@+id/acg"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_centerInParent="true"

android:layout_marginTop="50dp"

android:src="@color/colorAccent"/>

动画不变,还是设置80%p

效果图:

ezgif.com-video-to-gif.gif

啊嘞,咱们的粉色的 view 怎么没了,啦啦啦,大伙不知道平时注意没有,viewGroup 是不允许子控件超出自己的范围的,所以咱们的 view 在位移出父控件的范围后就消失不见了,这里我们需要设置一下:

需要在布局根节点设置android:clipChildren="false"才行,注意不是在这个父控件设置,是在 xml 的根节点设置,这点要注意啊,看我的这篇文章 Android 布局小技巧汇总

xml 根节点设置 android:clipChildren="false" 才行

Snip20170724_20.png

效果图:

ezgif.com-video-to-gif.gif

这样接可以看到效果了,这次位移的幅度就是我们添加的这个200dp 的父控件了

scale 缩放动画

效果图:

ezgif.com-video-to-gif.gif

这是缩放的效果,和预想的有点不同的是,缩放中心点怎么不是 view 的中心呢,那么我们来看下 xml 代码:

android:duration="600"

android:fillAfter="true"

android:fromXScale="1"

android:fromYScale="1"

android:toXScale="0.3"

android:toYScale="0.3"

/>

恩,看上面的 xml 设置中,里面没有设置缩放中心点的参数,那么上面的缩放就是走的是默认设置了,可以看到:缩放的默认中心点是 view 的左上角,这也是 tween 动画坐标系的原点,从这一点考虑也是可以理解默认中心点在左上角的设置了。

上面 xml 中属性的设置很好理解,fromXX是动画开始的数值,toXX 是动画结束时的数值,这里说一下,缩放的数值 1 是原始大小,0是没有大小,2是原始大小的2倍,所以说缩放的参数很好理解。

上面没写缩放中心点设置,那么当然中心点也是可以设置的,参数是:pivotX/pivotY,中心点的坐标,比如中心点设置在 view 的中心,数值可以这样写:50% 。写0.5表示偏移量是px 值。50%p表示中心点在view 的左上角坐标+父容器的宽高的一半之后的位置

xml

android:duration="600"

android:fillAfter="true"

android:fromXScale="1"

android:fromYScale="1"

android:pivotX="50%"

android:pivotY="50%"

android:toXScale="0.3"

android:toYScale="0.3"

/>

效果图:

ezgif.com-video-to-gif.gif

rotate 旋转动画

效果图:

ezgif.com-video-to-gif.gif

xml:

android:duration="600"

android:fillAfter="true"

android:fromDegrees="0"

android:pivotX="50%"

android:pivotY="50%"

android:toDegrees="360"

/>

rotate 和 scale 差不多,除了数值不同,其他都一样。rotate 因为是旋转,所以参数肯定是设置的旋转多少度,需要注意的是正数是顺时针转,负数是逆时针转,其他的没什么可说的了。

alphe 透明度动画

效果图:

ezgif.com-video-to-gif.gif

xml:

android:duration="600"

android:fillAfter="true"

android:fromAlpha="1"

android:toAlpha="0"

/>

哈哈,看完上面的 alphe透明度动画很简单了吧,注意数值1是不透明,0是完全透明。

tween动画的 repeat 重复模式

translate 的第一个效果图就是使用了动画的重复模式的,简单的说重复模式就是在动画结束后对 view 进行一些逻辑上的操作,可以重复执行和反向执行。

这里设计到2个参数设置: repeatMode / repeatCount,重复模式 / 重复次数

先看一下xml 的属性设置

android:duration="600"

android:fillAfter="true"

android:fromXDelta="0"

android:fromYDelta="0"

android:repeatCount="1"

android:repeatMode="reverse"

android:toXDelta="80%"

android:toYDelta="80%"

/>

这里一个位移动画,里面设置有重复模式和重复次数。首先说明一下,repeatMode和repeatCount二者缺一不可,必须都得写才能生效

repeatMode 分2种:

reverse 反向执行动画,就是动画时怎么来的,就怎么回去

restart 重复执行动画,就是动画反复执行,不过注意动画结束后就会回到初始位置,显得有些突兀

我们来看看效果是什么样的,这样才好理解不是,注意这里 repeatCount 都是设置为1

reverse 反向执行效果图:

ezgif.com-video-to-gif.gif

restart 重复执行效果图:

ezgif.com-video-to-gif.gif

这里使用了高采样率转换的 gif,可以很 清楚的看出来在第一次动画执行完后瞬间 view 就回归到了初始位置再执行了一次动画,中间切换的效果太突兀了,不是很友好。

好了看完了 repeatMode ,那么大家来猜测下 repeatCount 重复次数的使用规律,其实看完上面的都应该明白了,重复次数是指动画在执行完成后再按照某种方式执行多少次,我们写在 repeatCount 里面的数字是不包含第一次的,注意这点基本就可以了,比如我们想让上面这个动画来回执行2个大循环,既动画执行完后反向执行一次这算一个大循环,那么repeatCount我们写几呢,是3,不算第一次,大伙算算,自己试试,下面是效果图:

ezgif.com-video-to-gif.gif

好了是不是很咱们想的一样,自己多动手,多试试,google 的 api 基本我们都能搞明白。

AnimationSet 动画集合

android 中的动画不单单可以单独执行一种效果,更是可以多个动画效果一起执行的。下面看个例子:

android:duration="600"

android:interpolator="@android:anim/accelerate_decelerate_interpolator"

android:shareInterpolator="true">

android:fromXDelta="0"

android:fromYDelta="0"

android:repeatCount="1"

android:repeatMode="reverse"

android:toXDelta="80%"

android:toYDelta="80%"/>

android:fromAlpha="1"

android:repeatCount="1"

android:repeatMode="reverse"

android:toAlpha="0.2"/>

效果图:

ezgif.com-video-to-gif.gif

单个动画中有的参数可以写到 set 动画集合中去,比如时间,但是重复这块就不行了,我需要写到单个里才行

set 中有2个新的属性 interpolator 这个是插值器,是控制动画执行曲线的,系统提供的默认值就够我们使用的了,shareInterpolator 是设置所有的单项动画是否都使用 set 中的这个插值器,具体的插值器我们下节说,一看就懂

监听方法

差点忘了动画是可以加监听的,很多时候我们在动画执行完成后要做点什么不是嘛

animation1.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

}

@Override

public void onAnimationRepeat(Animation animation) {

}

});

AniamtionSet 动画集合也是可以添加监听的。上面的代码中提供了3个回调函数,中规中矩,开始,结束,重复。

总结

好了最后让我们来总结下使用时的注意点:

4种动画,位移支持3种参数形式,其他的不行

重复模式和重复次数要搞清楚

tween 动画虽然现在用的机会很少了,但是这是 android 动画的基础,之后的属性动画在使用时参数也是大体没有变化的。所以学好 tween 动画,有其是期中一些参数的数值范围,效果是很有必要的。好了就这么多了,更多的在参考资料里啦

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值