顺便学习一下Kotlin语言
介绍
动画能带来良好的用户体验,作为Android程序员,必须掌握最最最基本的几种动画实现方式,包括透明度,位移,旋转,缩放.
属性动画
属性动画是Android 3.0推出的动画框架,能实现视图动画所有动画效果,并且能完成视图动画不具备的功能. 例如一个在左上角的按钮使用视图动画将他移动到右下角,点击时候发现原来的点击监听已经不起作用了. 简单说,视图动画仅仅改变了控件的绘制,并没有改变其属性值.如果使用属性动画将它移动,那么原来的监听还是有的,这是真正的移动啊.属性动画就是这么强大
属性动画最重要的两个类
- ValueAnimator
- ObjectAnimator
原理:
属性动画作用于任何对象, 变化的属性名必须有该对象要有对应的getXXX和setXXX方法.
下面逐一讲讲
ValueAnimator
1 2 3 4 5 6 7 8
| fun startValueAnimation(){ val valueAnimator = ValueAnimator.ofFloat(0f,1f) valueAnimator.duration = 3000 valueAnimator.repeatCount = 2 valueAnimator.repeatMode = ValueAnimator.RESTART //重复 //valueAnimator.repeatMode = ValueAnimator.REVERSE //倒回 valueAnimator.start() }
|
- ofFloat()传入的值类型为float, 表示该值从1f 变化到 3f, 1f是初始值, 3f是最终值, ofFloat()传入的是可变参数, 即可以传入多个值,表示变化过程, 如: ofFloat(1f, 3f, 2f, 5f), 这里逐步并不是一下子从1f直接变化到3f,而是有个过程,每个过程值都不一样,
- 也许这里看不到变化, 但是动画所设置的值是变化了的,
ObjectAnimator
ObjectAnimator继承了ValueAnimator, 所以可以使用父类方法对动画进行一些通用设置, 不同的是创建ObjectAnimator对象
透明动画
1 2 3 4 5
| fun startAlpha(view: View){ val alphaAnimator = ObjectAnimator.ofFloat(view,"alpha", 1f,0f,1f) alphaAnimator.duration = 1000 alphaAnimator.start() }
|
- view: 动画作用的对象
- “alpha”: 值变化属性名, 及view对象中必须要有getAlpha()和serAlpha()方法,
- 1f,0f,1f: 表示变化过程, 不透明->全透明->不透明
旋转动画
如旋转30度:
1 2 3 4 5
| fun startRotate(view: View){ val rotateAnimator = ObjectAnimator.ofFloat(view,"rotation", 0f,360f) rotateAnimator.duration = 1000 rotateAnimator.start() }
|
位移动画
X轴位移
1 2 3 4 5 6
| fun startTranslateX(view: View){ val currentX: Float= view.translationX val translateXAnimator = ObjectAnimator.ofFloat(view,"translationX",currentX,-500f,currentX,500f,currentX) translateXAnimator.duration = 1000 translateXAnimator.start() }
|
- currentX: view原来的X坐标值
- 动画过程,从原来位置开始,左移500像素,回到原来位置,右移500像素,回到原来位置
Y轴位移
1 2 3 4 5 6
| fun startTranslateY(view: View){ val currentY: Float= view.translationY val translateYAnimator = ObjectAnimator.ofFloat(view,"translationY",currentY,-500f,currentY,500f,currentY) translateYAnimator.duration = 1000 translateYAnimator.start() }
|
缩放动画
同样,支持X方向 和Y方向
X轴缩放
1 2 3 4 5
| fun startScaleX(view: View){ val scaleXAnimator = ObjectAnimator.ofFloat(view,"scaleX",1F,3F,1F) scaleXAnimator.duration = 1000 scaleXAnimator.start() }
|
动画集合
1 2 3 4 5 6 7 8 9 10 11 12 13
| fun startAnimatorSet(view: View){ val animatorSet = AnimatorSet() val alphaAnimator = ObjectAnimator.ofFloat(view,"alpha", 1f,0f,1f) val rotateAnimator = ObjectAnimator.ofFloat(view,"rotation", 0f,360f) val scaleXAnimator = ObjectAnimator.ofFloat(view,"scaleX",1F,3F,1F) animatorSet.play(alphaAnimator).after(rotateAnimator).after(scaleXAnimator) animatorSet.duration = 2000 animatorSet.start() }
|
使用XML动画
在res建立animator文件夹
在animator下创建动画的xml文件,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"> </objectAnimator> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"> </objectAnimator> <set android:ordering="together"> <objectAnimator android:propertyName="rotation" android:duration="1000" android:valueFrom="0" android:valueTo="360" android:valueType="floatType"> </objectAnimator> <set android:ordering="sequentially"> <objectAnimator android:propertyName="scaleY" android:duration="500" android:valueFrom="1" android:valueTo="3" android:valueType="floatType"> </objectAnimator> <objectAnimator android:propertyName="scaleY" android:duration="500" android:valueFrom="3" android:valueTo="1" android:valueType="floatType"> </objectAnimator> </set> </set> </set>
|
在代码中这样调用
1 2 3 4 5
| fun startXMLAnimation(view: View){ val animator = AnimatorInflater.loadAnimator(this,R.animator.animator_test) animator.setTarget(view) animator.start() }
|
视图动画
透明度动画
1 2 3 4 5 6 7 8
| /** * 1:不透明 * 0:全透明**/ fun startAlpha(){ val alphaAnimation = AlphaAnimation(0f,1f) alphaAnimation.duration = 1000 tv_target?.startAnimation(alphaAnimation) }
|
旋转动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| /** * 参数1: 开始角 * 参数2: 旋转角 * 参数3: **/ fun startRotate(){ //val rotateAnimation = RotateAnimation(0f,360f,0f,0f) //以自身中心旋转 val rotateAnimation = RotateAnimation( 0f,360f, RotateAnimation.RELATIVE_TO_SELF,0.5F, RotateAnimation.RELATIVE_TO_SELF,0.5F ) rotateAnimation.duration = 1000 tv_target?.startAnimation(rotateAnimation) }
|
位移动画
1 2 3 4 5 6 7 8 9 10
| /** * fromX * toX * fromY * toY**/ fun startTranslate(){ val translateAnimation = TranslateAnimation(0f,200f,0f,300f) translateAnimation.duration = 1000 tv_target?.startAnimation(translateAnimation) }
|
缩放动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| /** * fromX * toX * fromY * toY**/ fun startScale(){ //val scaleAnimation = ScaleAnimation(0f,2f,0f,2f) //设置中心点缩放 val scaleAnimation = ScaleAnimation(0f,2f,0f,2f, ScaleAnimation.RELATIVE_TO_SELF,0.5F, ScaleAnimation.RELATIVE_TO_SELF,0.5F) scaleAnimation.duration = 1000 tv_target?.startAnimation(scaleAnimation) }
|
SVG动画
使用步骤
创建静态SVG图形
在drawable的资源文件夹下创建xml文件,line_svg_vector.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="200dp" android:width="200dp" android:viewportHeight="100" android:viewportWidth="100"> <group> <path android:name="path1" android:strokeColor="#3F51B5" android:strokeWidth="5" android:strokeLineCap="round" android:pathData="M 20,80 L 50,80,80,80"/> <path android:name="path2" android:strokeColor="#3F51B5" android:strokeWidth="5" android:strokeLineCap="round" android:pathData="M 20,20 L 50,20,80,20"/> </group> </vector>
|
创建动画资源xml文件
在animator下创建, 每个图形都要有一个动画过程
line_path_1.xml
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/bounce_interpolator" android:duration="500" android:propertyName="pathData" android:valueFrom="M 20,80 L 50,80,80,80" android:valueTo="M 20,80 L 50,50,80,80" android:valueType="pathType" > </objectAnimator>
|
line_path_2.xml
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/bounce_interpolator" android:duration="500" android:propertyName="pathData" android:valueFrom="M 20,20 L 50,20,80,20" android:valueTo="M 20,20 L 50,50,80,20" android:valueType="pathType" > </objectAnimator>
|
把静态SVG和动画资源联合起来
在drawable-v21目录下创建xml文件:line_animated_vector.xml
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/line_svg_vector"> <target android:animation="@animator/line_path_1" android:name="path1"/> <target android:animation="@animator/line_path_2" android:name="path2"/> </animated-vector>
|
使用SVG资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/id_svg_animation_activity_iv_line_svg" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center_horizontal" android:src="@drawable/line_animated_vector"/> <ImageView android:id="@+id/id_svg_animation_activity_iv_sun_system_svg" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center_horizontal" android:src="@drawable/sun_system_animated_vector"/> </LinearLayout>
|
开启动画
点击时候开启动画
1 2 3 4
| fun startLineSVGAnimation(imageView: ImageView){ val drawable = imageView.drawable (drawable as Animatable).start() }
|
kotlin语言