Android 动画

目录

一:动画简介

1、动画分类

2、补间动画和属性动画的区别

(1)补间动画

(2)属性动画

3、ValueAnimator类和ObjectAnimator区别

4、使用动画的注意事项:

五、插值器和估值器

二:帧动画:FrameAnimation

1、帧动画定义

2、帧动画使用

(1)将动画资源放到 drawable文件夹里

(2)设置 & 启动动画

步骤1:创建帧动画xml文件

步骤2:使用动画

三:补间动画:TweenAnimation

1、补间动画定义

2、Animation类基本属性

3、补间动画四种类型属性

(1)缩放scale常用属性

(2)alpha标签——调节透明度

(3)rotate标签——旋转

(4)translate标签 —— 平移

4、set标签——定义动作合集

5、补间动画使用

(1)使用方式

(2)新建动画文件

(3)代码使用

四、ValueAnimator

1、ValueAnimator介绍

2、ValueAnimator常用方法

3、监听器

4、代码

五、ObjectAnimator

1、简单使用代码

2、动画流程

(1)拼接set函数的

3、自定义ObjectAnimator属性

六、Interpolator插值器

1、系统的Interpolator

2、getInterpolation

 


一:动画简介

1、动画分类

Android动画可以分为ViewAnimation(视图动画)和PropertyAnimator(属性动画)。

视图动画包括补间动画(Tween Animation)和帧动画(FrameAnimation)。

属性动画包括ValueAnimator和ObjectAnimator。

2、补间动画和属性动画的区别

(1)补间动画

1、补间动画只能够作用在视图View上。只可以对view进行平移、缩放、旋转、透明度操作,不能对view的属性颜色长度进行变化。

2、补间动画没有改变view的属性,只是改变视觉效果。比如按钮从左上角移动到右下角。点击右下角的按钮是无效的。因为实际按钮还在左上角。

3、补间动画效果单一,遇到复杂的动画效果无法实现。

补间动画原理:补间动画是通过ParentView来不断调整ChildView的画布canvas坐标系来实现的,并没有修改任何view属性。发生动画的其实是ParentView而不是该view,所以只能在原位置才能处理触摸事件。

(2)属性动画

属性动画是Android3.0(API11)后提供的一种全新动画模式。属性动画是通过改变控件内部的属性值来达到动画效果的。

3、ValueAnimator类和ObjectAnimator区别

这两者都属于属性动画,本质是一致的,先改变值,然后赋值给对象的属性从而实现动画效果。

二者的区别:ValueAnimator先改变值,然后手动赋值给对象的属性从而实现动画。ObjectAnimator先改变值,然后自动赋值给对象的属性从而实现动画。ObjectAnimator继承自ValueAnimator,更加智能,自动化程度更高。

4、使用动画的注意事项:

(1)OOM问题:这个问题容易出现在帧动画中,当图片数量较多且图片较大时容易出现OOM。这个在实际开发中注意,尽量避免使用帧动画。

(2)内存泄漏:在属性动画中有一类无限循环的动画,这类动画需要在Activity退出时及时停止。否则将导致activity无法释放从而造成内存泄漏。

(3)兼容性问题:动画在3.0以下的系统上有兼容性问题,要做好适配工作。可以使用开源库NineOldAndroids来兼容。

(4)使用动画的过程中,建议开启硬件加速,这样会提高动画的流畅性。

五、插值器和估值器

插值器决定当前动画进度(可以理解为动画的变化规律,匀速、加速、减速等。)

估值器Evaluator:通过插值器返回的参数计算当前动画的具体数值。

二:帧动画:FrameAnimation

1、帧动画定义

将动画拆分为帧的形式,按顺序播放一组预先定义好的图片。可以实现一些复杂的个性化动画效果。使用时避免使用尺寸较大的图片,否则会引起OOM。

2、帧动画使用

(1)将动画资源放到 drawable文件夹里

将组成帧动画的每一帧图片放到drawable文件夹下。

技巧:

1、找到自己需要的gif动画

2、用 gif分解软件(如 GifSplitter)将 gif 分解成一张张图片即可

(2)设置 & 启动动画

设置 & 启动帧动画有两种方式:在XML / Java代码(本文省略)。本文主要讲解xml如何实现。

步骤1:创建帧动画xml文件

在 res/anim的文件夹里创建loading_main.xml文件

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/a1"
        android:duration="90" />
     <!--省略中间的图片-->
    <item
        android:drawable="@mipmap/a13"
        android:duration="90" />
</animation-list>
步骤2:使用动画

1、在Java代码中载入 & 启动动画,可以在xml中设置动画资源,也可以在代码里设置。

 <!--1、可以在xml中设置动画资源,也可以在代码里设置-->
<ImageView
        android:id="@+id/img_frame"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/loading_main" />

2、代码设置动画资源

   iv.setImageResource(R.drawable.loading_main);

3、开始、结束帧动画

private var mAnimationDrawable: AnimationDrawable? = null
/**
 *  帧动画开始
 */
private fun frameAnimationStart() {
    mAnimationDrawable = img_frame.drawable as AnimationDrawable
    mAnimationDrawable?.start()
}
/**
 *  帧动画结束
 */
private fun frameAnimationStop() {
    mAnimationDrawable = img_frame.drawable as AnimationDrawable
    mAnimationDrawable?.stop()
}

三:补间动画:TweenAnimation

1、补间动画定义

通过确定动画开始的视图样式和结束的视图样式,中间过渡动画由系统补全来确定一个动画。有四种动画类型:平移translate、缩放scale、旋转rotate、透明度alpha。优点:已经封装好了基础的动画效果,使用简单方便。缺点:只能控制整体的效果,无法控制其属性。比如颜色、背景等。比如只能修改view的大小位置透明度和角度,但不能修改View的组件属性。如:颜色、背景、长度等。

2、应用场景:

1.Activity、Fragment的切换效果

2.视图组(ViewGroup)中子元素的出场效果。

3.视图中标准的基础的动画效果。

2、Animation类基本属性

  • android:duration动画持续时间,以毫秒为单位
  • android:fillAfter如果设置为true,控件动画结束时,将保持动画最后时的状态

注意:如果在set中设置fillAfter无效,要在set添加android:fillAfter=”true”

  • android:fillBefore如果设置为true,控件动画结束时,还原到开始动画前的状态
  • android:fillEnabled与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
  • android:repeatCount重复次数
  • android:repeatMode重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
  • android:interpolator设定插值器,其实就是指定的动作效果,比如弹跳效果等。

    3、补间动画四种类型属性

(1)缩放scale常用属性

android:fromXScale 起始的X方向上相对自身的缩放比例,浮点值,比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍;

android:toXScale 结尾的X方向上相对自身的缩放比例,浮点值;

android:fromYScale 起始的Y方向上相对自身的缩放比例,浮点值,

android:toYScale 结尾的Y方向上相对自身的缩放比例,浮点值;

android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,当为数值时,表示在当前View的左上角,即原点处加上50px,做为起始缩放点;如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。(具体意义,后面会举例演示)

android:pivotY 缩放起点Y轴坐标,取值及意义跟android:pivotX一样。

<scale xmlns:android="http://schemas.android.com/apk/res/android"   android:duration="1000"
android:fillAfter="true"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />

(2)alpha标签——调节透明度

android:fromAlpha 动画开始的透明度,从0.0 —1.0 ,0.0表示全透明,1.0表示完全不透明

android:toAlpha 动画结束时的透明度,也是从0.0 —1.0 ,0.0表示全透明,1.0表示完全不透明

(3)rotate标签——旋转

android:fromDegrees 开始旋转的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数

android:toDegrees 结束时旋转到的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数

android:pivotX 、pivotY 旋转起点X轴坐标

(4)translate标签 —— 平移

android:fromXDelta 起始点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述,这里就不再重讲

android:fromYDelta 起始点Y轴从标,可以是数值、百分数、百分数p 三种样式;

android:toXDelta 结束点X轴坐标

android:toYDelta 结束点Y轴坐标

4、set标签——定义动作合集

Set标签就可以将几个不同的动作定义成一个动画集合,可以同时进行动画;

<?xml version="1.0" encoding="utf-8"?>
<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"/>

  <rotate
    android:fromDegrees="0"
    android:toDegrees="720"
    android:pivotX="50%"
    android:pivotY="50%"/>

</set>

5、补间动画使用

(1)使用方式

补间动画使用方式分为两种,在xml代码或java代码里设置。

在xml代码中设置,动画的描述可读性更好。在java代码里,动画效果可以动态创建。

(2)新建动画文件

在res文件夹下,新建一个anim文件夹,然后再新建一个anim_scale_in.xml文件。

(3)代码使用

fun View.startScaleInAnim() {
//从XML文件中获取动画
val animation = AnimationUtils.loadAnimation(this.context, R.anim.anim_scale_in)
this.startAnimation(animation)
}

四、ValueAnimator

1、ValueAnimator介绍

ValueAnimator只负责对指定的数字区间进行动画运算,我们需要对运算过程进行监听,然后自己对控件做动画操作。

2、ValueAnimator常用方法

ofInt与ofFloat
void start()
void cancel()
ValueAnimator setDuration(long duration)
/**
* 获取ValueAnimator在运动时,当前运动点的值
 *要进行类型转换,根据ofInt或ofFloat转换为int或者float
*/
Object getAnimatedValue();
/**
* 设置循环次数,
 *0表示不循环,ValueAnimation.INFINITE表示无限循环。
*/
void setRepeatCount(int value)
/**
* 设置循环模式
* value取值有RESTART(正序重新开始),REVERSE(倒序重新开始),
*/
void setRepeatMode(int value)

3、监听器

/**
 * 监听器一:监听动画变化时的实时值
 */
public static interface AnimatorUpdateListener {
    void onAnimationUpdate(ValueAnimator animation);
}
addUpdateListener(AnimatorUpdateListener listener)
void removeUpdateListener(AnimatorUpdateListener listener);
void removeAllUpdateListeners();
/**
 * 监听器二:监听动画变化时四个状态
 */
public static interface AnimatorListener {
    void onAnimationStart(Animator animation);
    void onAnimationEnd(Animator animation);
    void onAnimationCancel(Animator animation);
    void onAnimationRepeat(Animator animation);
}
addListener(AnimatorListener listener)
void removeListener(AnimatorListener listener);
void removeAllListeners();

4、代码

private fun animationBegin() {
val animator = ValueAnimator.ofInt(0, 600)
animator.addUpdateListener { anim ->
val value = anim.animatedValue as Int
Log.e("===", value.toString())
/**
*  layout()函数中上下左右点的坐标是以屏幕坐标来标准的。
*  layout函数在改变控件位置时是永久性的,即通过更改控件left,top,right,bottom这四个点的坐标来改更改坐标位置的,
*  所以通过layout函数更改位置后,控件在新位置是可以响应点击事件的。
*/
tv_name.layout(value, value, value + tv_name.width, value + tv_name.height)
}
animator.duration = 1000
animator.start()
}

五、ObjectAnimator

1、简单使用代码

private fun doAnimation(view:View,interpolator: TimeInterpolator) {
    val translationX = ObjectAnimator.ofFloat(view, "translationX", 0f, 800f,100f)
val translationY = ObjectAnimator.ofFloat(view, "translationY", 0f, 800f,100f)
    valanimatorSet = AnimatorSet()
animatorSet.play(translationX).with(translationY)
animatorSet.interpolator =interpolator
animatorSet.duration = 2000
    animatorSet.start()
}

2、动画流程

动画设置流程:ObjectAnimator需要指定操作的控件对象,在开始动画时,到控件类中去寻找设置属性所对应的set函数,然后把动画中间值做为参数传给这个set函数并执行它。

(1)拼接set函数的

拼接set函数的方法:将”alpha”拼接成setAlpha()

强制将属性的第一个字母大写,然后与set拼接,就是对应的set函数的名字。注意,只是强制将属性的第一个字母大写,后面的部分是保持不变的。

图片

3、自定义ObjectAnimator属性

核心思想:在我们自定义的view里面,添加一个属性值对应的方法。

比如:ObjectAnimator.ofFloat(tv_name, "alpha", 1f, 0f, 1f)

那我们的自定义view中,就要有一个setAlpha()方法。
代码:

使用:
val animator = ObjectAnimator.ofFloat(point_view, "pointRadius", 0f, 300f, 100f)
animator.duration = 2000
animator.start()
核心是:pointRadius在自定义view中对应setPointRadius方法。
class Point {
    var mRadius: Float = 0F
    constructor(radius: Float) {
        this.mRadius = radius
    }
}
class MyPointView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var mPoint = Point(100f)
    override fun onDraw(canvas: Canvas?) {
        if (mPoint != null) {
            val paint = Paint()
            paint.isAntiAlias = true
            paint.setColor(Color.RED)
            paint.style = Paint.Style.FILL
            canvas?.drawCircle(300f, 300f, mPoint.mRadius, paint)
        }
        super.onDraw(canvas)
    }
    fun setPointRadius(radius: Float) {
        mPoint.mRadius = radius
        invalidate()//ui线程调用
    }
    fun getPointRadius():Float{
        return 50f
    }
}

六、Interpolator插值器

Interpolator插值器,可以指定动画变化的速度。可以理解为加速度。

1、系统的Interpolator

LinearInterpolator :默认的插值器,匀速。

AccelerateInterpolator:速度越来越快。

DecelerateInterpolator:速度越来越慢。

AccelerateDecelerateInterpolator 先加速后减速

BounceInterpolator:弹跳,动画结束,会有一段弹跳的动画。

AnticipateInterpolator

AnticipateOvershootInterpolator

CycleInterpolator

OvershootInterpolator

2、getInterpolation

public float getInterpolation(float input) {
    return input;
}

自定义Interpolator,主要重写getInterpolation方法。里面的input参数与任何我们设定的值没关系,只与时间有关,随着时间的增长,动画的进度也自然的增加,input参数就代表了当前动画的进度。而返回值则表示动画的当前数值进度

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值