1、视图动画
- 补间动画
- 帧动画
2、属性动画(3.0之后)
平移
旋转
缩放
透明度
帧动画
对于上述动画我们都可以使用XML实现或者使用代码实现。为了演示充分,前两种我们通过XML形式实现,后面两种我们通过代码实现。(两种相比较更推荐以XML形式去实现动画。这种方式写动画效果更简单易懂)
首先检查res下面是否有anim文件夹,如果没有的话,新建一个。
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:anim/overshoot_interpolator">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="300"
android:toYDelta="0"
android:repeatCount="infinite">
translate>
set>
translateView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.translate_animation))
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<rotate
android:pivotY="50%"
android:pivotX="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:repeatCount="infinite">
rotate>
set>
rotateView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.rotate_animation))
//缩放动画
val scaleAnimation = ScaleAnimation(0f,1f,1f,1f)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = Animation.INFINITE
scaleView.startAnimation(scaleAnimation)
//透明度动画
val alphaAnimation = AlphaAnimation(0f,1f)
alphaAnimation.duration = 2000
alphaAnimation.repeatCount = Animation.INFINITE
alphaView.startAnimation(alphaAnimation)
上面我们有提到视图动画大致可以细分到五种,我们上面实现了基本的四种,现在是另外一种。
帧动画其实就是对于一组图片的快速播放。这个实现也比较简单。它的实现过程可以分为如下几个步奏:
1、新建animation类型的drawble
2、以此drawble设置为某一个view的src
3、在代码中得到View的drawble并进行类型转换到AnimationDrawable
4、drawble.start()
1、新建drawable:frame_animation.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/a"
android:duration="200">
item>
<item
android:drawable="@drawable/b"
android:duration="200">
item>
<item
android:drawable="@drawable/c"
android:duration="200">
item>
<item
android:drawable="@drawable/d"
android:duration="200">
item>
<item
android:drawable="@drawable/e"
android:duration="200">
item>
<item
android:drawable="@drawable/f"
android:duration="200">
item>
<item
android:drawable="@drawable/g"
android:duration="200">
item>
animation-list>
2、将它设置为一个view的background
"@+id/frameView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="@dimen/activity_vertical_margin"
android:src="@drawable/frame_animation"/>
3、在代码中转换drawable
val frameAnimation = frameView.drawable as AnimationDrawable
4、开启动画
frameAnimation.start()
我们上面谈到Animation的时候都是对view使用单一的动画效果,事实上我们可以对View的效果进行我们想要的 叠加
案例:平移时旋转
这里我们通过XML方式实现
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<rotate
android:pivotY="50%"
android:pivotX="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:repeatCount="infinite">
rotate>
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="300"
android:toYDelta="0"
android:repeatCount="infinite">
translate>
set>
(靠下下的两个)
(这个不知道传上去就不动了,实际上都是可以动的)
在Android3.0之前是没有属性动画的。属性动画的提出很大一部分原因是视图动画的局限性:视图动画只是改变视图内容的位置,而不改变视图本身位置。
这句话的意思是什么呢?
假如你把一个button通过视图动画向右平移了100px,并且为动画设置了fillAfter。
当你开启此动画,这个button在视觉上就会从以前的位置移动到新位置。但是你会发现当button位置移动之后,button的点击事件“失效”了。实际上不是失效了,而是button还在以前的位置,只是在视觉上button换了新位置,而这个视觉上的新位置不能相应button的点击事件。所以,属性动画来了。(关于这点请读者自行验证,我以前遇到过这种问题,但是那时候不知道这些)
ObjectAnimator是属性动画里面最重要的一个实行类,创建一个ObjectAnimator只需要通过他的静态工厂类直接返回一个ObjectAnimator对象。
构造一个属性动画所需参数如下:
1、要操作的View
2、要操作的属性
3、属性变化的取值数组(是可变数组参数)
举个例子:属性动画实现平移
val animator = ObjectAnimator.ofFloat(propTranView,"translationX",0f,300f)
animator.duration = 1000
animator.repeatCount = Animation.INFINITE
animator.start()
关于ObjectAnimator的使用有一个很重要的事:我们想要操作的参数必须具有set和get,因为对于属性动画,系统内部会通过java反射来操作set函数,从而真实的改变对象的属性值。
如果一个属性没有set和get函数的话,我们也可以使用属性动画。只不过要换一种方式。
自定义属性类或者包装类来间接的给这个属性增加set或者get方法
举例:属性动画更改View自身大小(view的width和height不存在set函数)
companion object {
class WrapperView(val targetView:View){
fun getWidth():Int{
return targetView.width
}
fun setWidth(width:Int){
targetView.layoutParams.width = width
targetView.requestLayout() //请求重新layout
}
}
}
//属性动画:更改View自身宽度
val wrapper = WrapperView(propScaleView)
val animator1 = ObjectAnimator.ofInt(wrapper,"width",500)
animator1.duration = 1000
animator1.repeatCount = Animation.INFINITE
animator1.start()
它的作用类似视图动画里面的AnimationSet,当动画要作用于一个对象的多个属性时,我们可以使用PropertyValuesHolder来实现。
案例:平移时旋转
//属性动画:平移时旋转
val pvh1 = PropertyValuesHolder.ofFloat("translationX",300f)
val pvh2 = PropertyValuesHolder.ofFloat("rotation",360f)
val animator2 = ObjectAnimator.ofPropertyValuesHolder(propMultiView,pvh1,pvh2)
animator2.duration = 1000
animator2.repeatCount = Animation.INFINITE
animator2.start()
ValueAnimator是ObjectAnimator的父类。它本身并不提供动画效果,但是对象的属性数值变化是由它来控制。调用者根据它产生的一系列数值来控制动画的实现。
下面是ValueAnimator的一个基本使用方法:
//属性动画:通过ValueAnimator
val animator3 = ValueAnimator.ofFloat(0f,100f)
animator3.setTarget(propValueView)
animator3.duration = 1000
animator3.repeatCount = Animation.INFINITE
animator3.start()
animator3.addUpdateListener { animator:ValueAnimator->
//使用数值
}
参考:
Android群英传
Android开发艺术探索
Android分别通过代码和xml实现动画效果
自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法