美文网首页
自定义View之动画篇-属性动画

自定义View之动画篇-属性动画

作者: Active_Loser | 来源:发表于2018-10-23 00:01 被阅读0次

文章首发于个人博客
任何形式的转载都请联系作者获得授权并注明出处。

一、基本概念

属性动画就是在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果。

二、动画

1、View中的方法

我们可以对View调用以下属性实现动画

View中的方法 功能
setTranslationX()setTranslationY()setTranslationZ() 设置X、Y、Z轴平移
setX()setX()setX() 设置X、Y、Z轴绝对位置
setRotation()setRotationX()setRotationY() 设置平面、X、Y轴旋转
setScaleX()setScaleY() 设置X、Y方向缩放
setAlpha() 设置透明度

2、ValueAnimator

属性动画机制中最核心的一个类,ObjectAnimator和ViewPropertyAnimator都是通过这个这个实现的。ValueAnimator是通过不断控制值的变化,再不断添加属性,从而实现动画效果

使用方法

  1. 初始化ValueAnimator,设置各种属性
  2. 给ValueAnimator设置监听器,通过getAnimatedValue()拿到变化值后更新控件。
常用方法 功能
ofInt() 返回一个int型变化的ValueAnimator
ofFloat() 返回一个float型变化的ValueAnimator
ofObject 返回一个object型变化的ValueAnimator。

1.1、设置颜色变化

我们这里并没有使用ofArgb这个属性,因为这个方法是在API21以上使用的,在低版本上不兼容。

final View view = findViewById(R.id.view);
//以整型数值的形式,过渡到结束值
ValueAnimator animator = ValueAnimator.ofInt(0xffff00ff, 0xffffff00, 0xffff00ff);
//设置求值器
animator.setEvaluator(new ArgbEvaluator());
//设置动画的播放时长
animator.setDuration(1000);
//设置动画重复播放次数,ValueAnimator.INFINITE为无限重复
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int currentValue = (Integer) animation.getAnimatedValue();
         Log.i(TAG, "onAnimationUpdate: "+currentValue);
         view.setBackgroundColor(currentValue);
         view.requestLayout();
    }
});
animator.start();

1.2、ofObject()的使用

ofInt和ofFloat是针对Int值和Float值的变化,但是,我们只能控制一个值的变化,但是当我们需要实现多值变化时,它们就不再满足我们的需求。

//设置变化的值
ValueObject startObjectVal = new ValueObject(1f, 0);
ValueObject endObjectVal = new ValueObject(0f, 360);
ValueAnimator animator = ValueAnimator.ofObject(new Evaluator(), startObjectVal, endObjectVal);
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        view.setAlpha(((ValueObject) animation.getAnimatedValue()).alphaValue);
        //可以设置各种动画
        view.setRotation(((ValueObject) animation.getAnimatedValue()).rotateValue);
        view.requestLayout();
    }
});
animator.start();

》》设置估值器,估值器的作用觉得值得变化顺序《《

//下面具体讲解
class Evaluator implements TypeEvaluator<ValueObject> {
    @Override
    public ValueObject evaluate(float fraction, ValueObject startValue, ValueObject endValue) {
        float alphaValue = startValue.alphaValue + (endValue.alphaValue - startValue.alphaValue) *          fraction;
        float rotateValue = startValue.rotateValue + (endValue.rotateValue - startValue.rotateValue) * fraction;
        return new ValueObject(alphaValue, rotateValue);
    }
}

//创建对象,保存透明度和旋转的值得变化
class ValueObject {
    float alphaValue;//透明度
    float rotateValue;//旋转

    ValueObject(float alphaValue, float rotateValue) {
        this.alphaValue = alphaValue;
        this.rotateValue = rotateValue;
    }
}

1.3、属性和方法整理

常用的属性

方法 解释 方法 解释
setDuration 设置动画总时长,单位毫秒。 getDuration 获取动画总时长
setFrameDelay 设置每一帧之间间隔多少毫秒 getFrameDelay 获取每一帧之间间隔多少毫秒
setInterpolator 设置动画的插值器 getInterpolator 获取当前使用的插值器
setRepeatCount 设置重复次数 getRepeatCount 获取重复次数
setRepeatMode 设置重复模式。有RESTART(正序)和REVERSE(倒序) getRepeatMode 获取重复模式
setStartDelay 设置开始前延迟毫秒数 getStartDelay 获取开始前延迟毫秒数
getAnimatedValue 获取计算出来的当前属性值 getAnimatedValue 获取计算出来的当前某个属性的值
setEvaluator 设置求值器 setFloatValues 设置Float型变化值,设置初始值、中间值、结束值
setIntValues 设置Int型变化值,设置初始值、中间值、结束值 setObjectValues 设置Object型变化值,设置初始值、中间值、结束值

常用的方法

方法 解释 方法 解释
addUpdateListener 添加值变化监听器 addUpdateListener 添加动画状态监听器
start 开始动画 pause 暂停动画
resume 继续动画 cancel 取消动画
end 动画结束 reverse 倒序播放动画
isRunning 判断是否在正在运行 isStarted 判断是的开始播放

1.4、估值器和插值器(重点)

估值器--TypeEvaluator:决定值的具体变化顺序

估值器的使用我们上面已经学习过了,在这里对估值器的具体使用简单的解释。

//实现了TypeEvaluator接口
public class FloatEvaluator implements TypeEvaluator {  
    
    /**
    * fraction:表示动画完成度
    * startValue:动画的初始值
    * endValue:动画的结束值
    * /
    public Object evaluate(float fraction, Object startValue, Object endValue) {  
        //用初始值加上动画完成度乘以结束值和初始值之间的差值
    }  
}

插值器--Interpolator:决定值的速度变化顺序

使用方法:

setInterpolator(Interpolator interpolator)//设置速度插值器

常用的插值器:

  • LinearInterpolator:线性匀速变化
  • AccelerateDecelerateInterpolator:先加速再减速
  • AccelerateInterpolator:持续加速
  • DecelerateInterpolator:持续减速直到 0
  • AnticipateInterpolator:先回拉一下再进行正常动画轨迹
  • OvershootInterpolator:动画会超过目标值一些,然后再弹回来
  • AnticipateOvershootInterpolator:先回拉一下再进行正常动画轨迹,最后动画会超过目标值一些,然后再弹回来
  • BounceInterpolator:在目标值来回跳动

3、ObjectAnimator

直接对对象的属性值进行改变操作,从而实现动画效果,内部是有ValueAnimator实现,因此其也有ofXXX()方法,这里接受的参数不一样了,具体的就不整理了,常用属性和常用方法和ValueAnimator一致

使用方法:

  1. 对于自定义控件,使用setter / getter 方法;
  2. 调用 ObjectAnimator.ofXXX() 创建 ObjectAnimator 对象,设置常用属性。
  3. 调用 start() 方法执行动画

方法:ofFloat(Object target, String propertyName, float... values)

参数:

  • target:我们需要控制动画的对象

  • propertyName:设置动画效果(传入任意属性值)

    这里传入的参数,其实是调用了ValueAnimatorsetXXX()方法和getXXX()方法,具体的代码就不贴了。

    • alpha:透明度
    • rotationRotationXRotationY:旋转
    • translationXtranslationY:平移
    • ScaleXscaleY :缩放
    • values:自定义属性
  • values:值

》》自定义圆形进度条《《

完整代码在线地址:Github在线地址

ProPress.java

我们在Activity中,给动画设置了一个属性progress,我们在ProPress.java中,用getProgress()setProgress方法,这样系统会自动调用该对象属性的set() & get()方法进行赋值。

/**
 * Created by Active_Loser on 2018/10/22.
 * Content: 自定义圆形进度条
 */
public class ProPress extends View {

    //.....
    private int progress = 0;

    public float getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }
    
    //.....
    
    @Override
    protected void onDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        //绘制圆弧
        RectF arcRectF = new RectF(20, 20, width-20, height-20);
        //progress设置值为0-100,因此需要乘3.6
        canvas.drawArc(arcRectF, 135, progress * 3.6f, false, mArcPaint);
        canvas.drawText(progress + "%", width/2, height/2-(mArcPaint.ascent() + mArcPaint.descent()) / 2, mTextPaint);
    }
}

XML:

<com.example.active.loser.views.level3.ProPress
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:layout_centerInParent="true"
    android:id="@+id/view"/>

Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ProPress view = findViewById(R.id.view);
    // 创建 ObjectAnimator 对象
    ObjectAnimator animator = ObjectAnimator.ofInt(view, "progress", 0, 100);
    //持续时长4秒
    animator.setDuration(4000);
    animator.setInterpolator(new FastOutSlowInInterpolator());
    animator.start();
}

4、ViewPropertyAnimator

ValueAnimator、ObjectAnimator、ViewPropertyAnimator三者使用难度和灵活性逐渐递减,因此我们尽量选择简单的使用

使用方法

view.animate().动画();  

常用的动画如下表所示:

View中的方法 对于中的方法ViewPropertyAnimator 功能
setTranslationX() translationX()translationXBy() 设置X轴平移
setTranslationY() translationY()translationYBy() 设置Y轴平移
setTranslationZ() translationZ()translationZBy() 设置Z轴平移
setX()setX()setX() x()xBy()y()yBy()z()zBy() 设置X、Y、Z轴绝对位置
setRotation() rotation()rotationBY() 设置平面轴旋转
setRotationX() rotationX()rotationXBy() 设置X轴旋转
setRotationY() rotationY()rotationYBy() 设置Y轴旋转
setScaleX() scaleX()scaleX()By 设置X方向缩放
setScaleY() scaleY()scaleYBy() 设置Y方向缩放
setAlpha() alpha()alphaBy() 设置透明度

特点:

  • by:变化偏移、无by:变化到

    即:加上By的意思是,继续动画这么多数值,不加By的意思是动画到这个数值。

简单的使用:

view.animate()
.setDuration(5000)
.zBy(10)
.setInterpolator(new BounceInterpolator())
.setStartDelay(1000)
.withLayer()//是否开启硬件加速
//监听
.setListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
    }
    @Override
    public void onAnimationEnd(Animator animation) {
    }
    @Override
    public void onAnimationCancel(Animator animation) {
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
})
.setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    }
})
.withEndAction(new Runnable() {
    @Override
    public void run() {
    }
})
.withStartAction(new Runnable() {
    @Override
    public void run() {
    }
})
.start();

相关文章

  • 动画深入研究

    前言 分类 View动画,帧动画,自定义View动画,属性动画 View动画 平移,缩放,旋转,透明Transla...

  • Android知识总结

    一、Android动画 Android 属性动画:这是一篇很详细的 属性动画 总结&攻略 二、自定义View 爱哥...

  • 自定义view(三)----自定义字体变色

    上一篇文章我们使用属性动画实现了自定义view的动画效果,这篇文章主要是结合属性动画自定义一个文字变色的view。...

  • Android开发之帧动画

    Android动画主要分为3种 View动画(Android开发之View动画) 帧动画 属性动画 何为帧动画? ...

  • Android - 自定义View和属性动画 ValueAnim

    自定义View和属性动画ValueAnimator实现圆点指示器 自定义View和属性动画相结合实现支持动态修改指...

  • Hencoder学习笔记1-6

    HenCoder Android 自定义 View 1-6: 属性动画(上手篇) Transition Anima...

  • Android动画深入分析

    导语 本章学习内容:介绍View动画和自定义View动画,View动画一些特殊的使用场景,对属性动画全面性的介绍,...

  • 自定义View之动画篇-属性动画

    文章首发于个人博客任何形式的转载都请联系作者获得授权并注明出处。 一、基本概念 属性动画就是在一定时间间隔内,通过...

  • Android开发之View动画

    Android动画主要分为3种 View动画 帧动画 属性动画 何为View动画? View动画主要是对View对...

  • Hencoder学习笔记1-7

    【HenCoder Android 开发进阶】自定义 View 1-7:属性动画(进阶篇) 针对特殊类型的属性来做...

网友评论

      本文标题:自定义View之动画篇-属性动画

      本文链接:https://www.haomeiwen.com/subject/xnanzftx.html