安卓基本动画的使用及详解

安卓基本动画的使用及详解

每次使用到动画就感觉既熟悉又陌生,只知道大概流程,用到具体的方法,只知道有这样的一个方法,但是又不知到怎样调用出来,最终还是要行百度搜索一下资源,让后复制到项目中,下次使用时 依然会忘记,所以这里写一篇博客笔记,记录一下,加深一下印象,希望以后用到动画可以,随手敲来.也希望对看这篇博客的小伙伴有所帮助.

安卓动画的介绍

  • View Animation: 这个动画是安卓一直都有的,但是它又一个局限性,就是只能用在View上面,不够强大

  • Drawable Animation: 帧动画,(也叫frame动画),类似与GIF图片,是将一组图片,在极短的时间内连续播放,造成视觉错误,看着类似是在动,其实是一组静态的图片高速播放造成的效果

  • Animator 属性动画,这个是安卓3.0才加进来的(API 11)才添加进来的.这种动画可以设置给Object(任何对象或者属性)也是使用最多的一个动画,支持扩展等非常灵活…

当前应用程序开发涉及的主要动画也就这三大类,我们接下来以类别为基础来慢慢展开说明。

2 View Animation(视图动画)使用详解

2.1视图动画又称(补间.(twn)动画)

可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。譬如,如果你有一个TextView对象,您可以移动、旋转、缩放、透明度设置其文本,当然,如果它有一个背景图像,背景图像会随着文本变化。

补间动画有两种实现的方式,一种是以xml布局文件实现的,一种是以代码直接编辑实现,两者均可,但是一布局文件实现的,重用性高,代码更加简洁.但是要创建一个新的文件,所以大家视情况和喜好决定吧.

先来看一下补间动画有几种,以下是补间动画的集成关系
这里写图片描述

java类名关键字及目录动画描述
AlphaAnimation 放置在res/anim/目录下渐变透明度动画效果
RotateAnimation 放置在res/anim/目录下画面转移旋转动画效果
ScaleAnimation 放置在res/anim/目录下渐变尺寸伸缩动画效果
TranslateAnimation 放置在res/anim/目录下画面转换位置移动动画效果
AnimationSet 放置在res/anim/目录下一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器

先介绍第一种布局文件实现:

xml属性详解

xml属性java方法解释
android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行
android:durationsetDuration(long)动画持续时间,毫秒为单位
android:fillAftersetFillAfter(boolean)控件动画结束时是否保持动画最后的状态
android:fillBeforesetFillBefore(boolean)控件动画结束时是否还原到开始动画前的状态
android:fillEnabledsetFillEnabled(boolean)与android:fillBefore效果相同
android:interpolatorsetInterpolator(Interpolator)设定插值器(指定的动画效果,譬如回弹,加速,减速等)
android:repeatCountsetRepeatCount(int)重复次数
android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放
android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒
android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal

以上是所有补间动画都共同具备的属性(方法).接下来介绍一下,不同的补间动画,所独自拥有的属性(方法).

2.1.2 alpha(透明)的属性

xml属性java方法解释
android:fromAlphaAlphaAnimation(float fromAlpha, …)动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)
android:toAlphaAlphaAnimation(…, float toAlpha)动画结束的透明度,同上

2.1.3 Rotate(旋转)的属性

xml属性java方法解释
android:fromDegreesRotateAnimation(float fromDegrees, …)旋转开始角度,正代表顺时针度数,负代表逆时针度数
android:toDegreesRotateAnimation(…, float toDegrees, …)旋转结束角度,正代表顺时针度数,负代表逆时针度数
android:pivotXRotateAnimation(…, float pivotX, …)缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYRotateAnimation(…, float pivotY)缩放起点Y坐标,同上规律

2.1.4 Scale(缩放)属性详解

xml属性java方法解释
android:fromXScaleScaleAnimation(float fromX, …)初始X轴缩放比例,1.0表示无变化
android:toXScaleScaleAnimation(…, float toX, …)结束X轴缩放比例
android:fromYScaleScaleAnimation(…, float fromY, …)初始Y轴缩放比例
android:toYScaleScaleAnimation(…, float toY, …)结束Y轴缩放比例
android:pivotXScaleAnimation(…, float pivotX, …)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYScaleAnimation(…, float pivotY)缩放起点Y轴坐标,同上规律

2.1.5 Translate属性详解

xml属性java方法解释
android:fromXDeltaTranslateAnimation(float fromXDelta, …)起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:fromYDeltaTranslateAnimation(…, float fromYDelta, …)起始点Y轴从标,同上规律
android:toXDeltaTranslateAnimation(…, float toXDelta, …)结束点X轴坐标,同上规律
android:toYDeltaTranslateAnimation(…, float toYDelta)结束点Y轴坐标,同上规律

2.1.6 AnimationSet详解

AnimationSet继承自Animation,是上面四种的组合容器管理类,没有自己特有的属性,他的属性继承自Animation,所以特别注意,当我们对set标签使用Animation的属性时会对该标签下的所有子控件都产生影响。

2.17 下面为啦复制方便给出一个简单的代码示例

布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fillAfter="true"
    android:fillBefore="false"
    android:repeatCount="2"
    android:repeatMode="reverse">
    <!--设置在set中的属性会对包含在set中的动画全部生效   这里设置了时间,和保留动画后的位置,以及重复模式是,反转-->
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0.5" />
    <rotate
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <!--这里是平移y轴自身高度的30%-->
    <translate
        android:repeatCount="2"
        android:toXDelta="20%"
        android:toYDelta="30%" />
    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="1.5 "
        android:toYScale="1.5" />
</set>

布局的引用

  animationSet = (AnimationSet) AnimationUtils.loadAnimation(this, R.anim.set_animtion);
        imageView.startAnimation(animationSet);
  • 其中注意在set标签下设置android:repeatCount=”2”虽然不报错但是其实是无效的,重复的次数必须设置到子标签中才会生效,其他在set标签下写的属性,都是公用的,既子标签相当于集成了 set里面设置的属性 android:repeatCount=”2”除外

这里写图片描述

2.1.8 java代码示例

             TranslateAnimation translateAnimation=new TranslateAnimation(0,100,0,100);
                translateAnimation.setDuration(2000);
                translateAnimation.setRepeatMode(Animation.REVERSE);
                translateAnimation.setRepeatCount(3);
                translateAnimation.setFillAfter(true);

                RotateAnimation rotateAnimation=new RotateAnimation(0,720);
                rotateAnimation.setDuration(2000);
                rotateAnimation.setRepeatMode(Animation.REVERSE);
                rotateAnimation.setRepeatCount(2);
                rotateAnimation.setFillAfter(true);
                AnimationSet animationSet=new AnimationSet(true);
                animationSet.addAnimation(rotateAnimation);
                animationSet.addAnimation(translateAnimation);

                imageView.startAnimation(animationSet);
  • 注意代码方式实现道理跟布局实现的累死, rotateAnimation.setRepeatCount(2);这个重复次数也是要分别设置到TranslateAnimation 和RotateAnimation 等上面,其他属性如播放时长,重复模式等可以由AnimationSet 统一设置

2.1.9Animation还有如下一些比较实用的方法介绍:

Animation类的方法解释
reset()重置Animation的初始化
cancel()取消Animation动画
start()开始Animation动画
setAnimationListener(AnimationListener listener)给当前Animation设置动画监听
hasStarted()判断当前Animation是否开始
hasEnded()判断当前Animation是否结束

既然补间动画只能给View使用,那就来看看View中和动画相关的几个常用方法吧,如下:

View类的常用动画操作方法解释
startAnimation(Animation animation)对当前View开始设置的Animation动画
clearAnimation()取消当View在执行的Animation动画

2.2 视图动画Interpolator插值器详解

2.2.1 插值器简介

介绍补间动画插值器之前我们先来看一幅图,如下:
这里写图片描述

可以看见其实各种插值器都是实现了Interpolator接口而已,同时可以看见系统提供了许多已经实现OK的插值器,具体如下:

java类xml id值描述
AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator动画始末速率较慢,中间加速
AccelerateInterpolator@android:anim/accelerate_interpolator动画开始速率较慢,之后慢慢加速
AnticipateInterpolator@android:anim/anticipate_interpolator开始的时候从后向前甩
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator类似上面AnticipateInterpolator
BounceInterpolator@android:anim/bounce_interpolator动画结束时弹起
CycleInterpolator@android:anim/cycle_interpolator循环播放速率改变为正弦曲线
DecelerateInterpolator@android:anim/decelerate_interpolator动画开始快然后慢
LinearInterpolator@android:anim/linear_interpolator动画匀速改变
OvershootInterpolator@android:anim/overshoot_interpolator向前弹出一定值之后回到原来位置
PathInterpolator新增,定义路径坐标后按照路径坐标来跑。

2.2.2自定义代码Interpolator

自定义的Interpolator 需要实现Interpolator接口
这里在给一个(差值器)Interpolator计算的 链接

http://inloop.github.io/interpolator/

public class ddd implements Interpolator {
    float f;
    public ddd(float f){
        this.f=f;

    }
    @Override
    public float getInterpolation(float input) {

        return (float) (Math. pow(2, -10 * input) * Math.sin((input - f / 4) * (2 * Math.PI) / f) + 1);
    }
}

自定义布局文件的 差值器 稍后补充

3-2 Drawable动画详细说明

我们依旧可以使用xml或者java方式实现帧动画。但是推荐使用xml,具体如下:

必须是根节点,包含一个或者多个元素,属性有:

android:oneshot true代表只执行一次,false循环执行。
<item> 类似一帧的动画资源。

animation-list的子项,包含属性如下:

android:drawable 一个frame的Drawable资源。
android:duration 一个frame显示多长时间。

3-3 Drawable动画实例演示

关于帧动画相对来说比较简单,这里给出一个常规使用框架,如下:

定义帧动画


<!-- 注意:rocket.xml文件位于res/drawable/目录下 -->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot=["true" | "false"] >
    <item
        android:drawable="@[package:]drawable/drawable_resource_name"
        android:duration="integer" />
</animation-list>

oneshot 是动画是否执行一次,给false 就会无限循环
duration 是没张动画的持续时长,不易过大,50~200为佳
drawable 是每次播放的图片

代码加载(使用)帧动画

ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();

三 接下来是重点,也是使用最多的动画(属性动画)

3.1.1这里重点介绍属性动画的ObjectAnimator和ValueAnimator

看一下Animator的继承关系
这里写图片描述

这里先介绍一下ObjectAnimator

先从最简单的开始,平时用的比较多的 对 View的操作(平移,旋转,透明,缩放)

ObjectAnimator的基本使用和基本方法参数解读

设置方式一: java代码设置

ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values);  

// ofFloat()作用有两个
// 1. 创建动画实例
// 2. 参数设置:参数说明如下
// Object object:需要操作的对象
// String property:需要操作的对象的属性
// float ....values:动画初始值 & 结束值(不固定长度)
// 若是两个参数a,b,则动画效果则是从属性的a值到b值
// 若是三个参数a,b,c,则则动画效果则是从属性的a值到b值再到c值
// 以此类推
// 至于如何从初始值 过渡到 结束值,同样是由估值器决定,此处ObjectAnimator.ofFloat()是有系统内置的浮点型估值器FloatEvaluator,同ValueAnimator讲解

anim.setDuration(500);
        // 设置动画运行的时长

        anim.setStartDelay(500);
        // 设置动画延迟播放时间

        anim.setRepeatCount(0);
        // 设置动画重复播放次数 = 重放次数+1
        // 动画播放次数 = infinite时,动画无限重复

        anim.setRepeatMode(ValueAnimator.RESTART);
        // 设置重复播放动画模式
        // ValueAnimator.RESTART(默认):正序重放
        // ValueAnimator.REVERSE:倒序回放

animator.start();  
// 启动动画

设置方法二:xml 布局设置

  • 注: 在路径 res/animator 的文件夹里创建动画效果.xml文件
 // ObjectAnimator 采用<animator>  标签
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
    android:valueFrom="1"   // 初始值
    android:valueTo="0"  // 结束值
    android:valueType="floatType"  // 变化值类型 :floatType & intType
    android:propertyName="alpha" // 对象变化的属性名称

/>

也可以以set 为跟标签,里面嵌条一些不同的动画,做成一个一个动画集AnimatorSet

在java文件中使用该动画

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.view_obg_alpha);  
// 载入XML动画

animator.setTarget(view);  
// 设置动画对象

animator.start();  
// 启动动画
  • a) alpha (透明动画)
 ObjectAnimator alphaObj=ObjectAnimator.ofFloat(iv_cang,"alpha",0,1);
                // 操作的对象  操作的属性(动画属性)  如何动画
                alphaObj.setRepeatCount(1);//重复次数  实际播放次数是设置的次数+1
                alphaObj.setDuration(2000);//播放时长
                alphaObj.start();//启动动画

透明动画效果图ll/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

  • b) rotation(旋转)动画
  ObjectAnimator rotationAnmiator=ObjectAnimator.ofFloat(iv_cang,"rotation",0,360);
                rotationAnmiator.setDuration(2000);
                rotationAnmiator.start();

旋转效果图

  • c)scale (缩放动画)
 ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(iv_cang,"scaleX",1,2,1);
                scaleAnimator.setDuration(2000);
                scaleAnimator.start();

缩放效果图

  • d) translation(平移) 动画
 ObjectAnimator translation = ObjectAnimator.ofFloat(iv_cang,"TranslationX",0,200);
                translation.setDuration(2000);
                translation.start();

平移效果图这里只是平移了水平方向

这里列出基本的动画的传入的值代表的意思
属性 作用 数值类型

Alpha控制View的透明度float
TranslationX控制X方向的位移float
TranslationY控制Y方向的位移float
ScaleX控制X方向的缩放倍数float
ScaleY控制Y方向的缩放倍数float
Rotation控制以屏幕方向为轴的旋转度数float
RotationX控制以X轴为轴的旋转度数float
RotationY控制以Y轴为轴的旋转度数float
  • 在ObjectAnimator.ofFloat()的第二个参数String property可传入alpha、rotation、translationX 和 scaleY 等值
  • 还可以传入什么值呢这个第二个参数, 其实这个参数是可以传入任意值的(即任意的字符串)

2.2.0 为什吗ObjectAnimator.offloat()方法的第二个参数可以传入任意值呢?

  • ObjectAnimator 类 对 对象属性值 进行改变从而实现动画效果的本质是:通过不断控制 值 的变化,再不断 自动 赋给对象的属性,从而实现动画效果

  • 而 自动赋给对象的属性的本质是调用该对象属性的set() & get()方法进行赋值

  • 所以,ObjectAnimator.ofFloat(Object object, String property, float ….values)的第二个参数传入值的作用是:让ObjectAnimator类根据传入的属性名 去寻找 该对象对应属性名的 set() & get()方法,从而进行对象属性值的赋值,如上面的例子:

等看完下面这个例子你估计就会更加明白一点了.
//下面的例子是借鉴网上的,自己写重复写了一遍

2.2.1 实现自定义对象的动画

主要实现两个重要的步骤

  • 为对象设置需要操作属性的set() & get()方法
  • 通过实现TypeEvaluator类从而定义属性变化的逻辑

现在我们介绍一下ObjectAnimator.ofObject()方法.

实现一个自定义圆的颜色渐变

  • 第一步 给自定义对象加上要用的get() set() 方法
    – 方法一:通过继承 增加get() set() 方法
    – 方法二:通过自定义包装类,设置对象的值
    这里先讲第一种方法,第二种方法稍后给出例子

MyView1.java

package qst.com.mydonghuahejidemo.MyView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by user on 2017/10/19.
 */

public class MyView1 extends View {
    public MyView1(Context context) {
        super(context);
        initPaint();
    }

    public MyView1(Context context,  @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    Paint mPaint;
    String mColor="#00ff00";
//    定义设置Color的get() set 方法
    public String getColor(){
        return mColor;
    }
    public void setColor(String color){
        this.mColor=color;
        //将画笔的颜色设置成 传递进来的颜色
        mPaint.setColor(Color.parseColor(color));
        invalidate();
        //调用重新绘制的方法,重新绘制,调用invalidate()其实相当于重新走了一遍onDraw()方法,重新绘制图案.
    }

//自定义三部曲  onMeasure计算自己的大小  onLayout给自己的孩子指定位置  onDraw绘制自己最终的样子
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    /**
     * 初始化画笔
     */
    private void initPaint(){
//        mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint=new Paint();
        mPaint.setStyle(Paint.Style.FILL);//模式是填充
        mPaint.setAntiAlias(true);//抗锯齿
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //圆心  半径  画笔
        canvas.drawCircle(200,200,100,mPaint);

    }
}
  • 第二步 加入到布局中并且在java文件中初始化(findViewById)
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
<qst.com.mydonghuahejidemo.MyView.MyView1
            android:id="@+id/myView1"
            android:layout_width="400dp"
            android:layout_height="200dp" />

        <Button
            android:id="@+id/btn_color"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="小球变色" />
    </LinearLayout>
  • 第三步 自定义估值器(不是差值器)
    估值器是整个动画过程中实际值的变化,差值器是计算值动画的实际路线,两者有联系,但不一样

ColorEvaluator .java 实现颜色过渡的逻辑

package qst.com.mydonghuahejidemo.MyView;

import android.animation.TypeEvaluator;

public class ColorEvaluator implements TypeEvaluator {
    // 实现TypeEvaluator接口

    private int mCurrentRed;

    private int mCurrentGreen ;

    private int mCurrentBlue ;

    // 复写evaluate()
    // 在evaluate()里写入对象动画过渡的逻辑:此处是写颜色过渡的逻辑
    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue) {

        // 获取到颜色的初始值和结束值
        String startColor = (String) startValue;
        String endColor = (String) endValue;

        // 通过字符串截取的方式将初始化颜色分为RGB三个部分,并将RGB的值转换成十进制数字
        // 那么每个颜色的取值范围就是0-255
        int startRed = Integer.parseInt(startColor.substring(1, 3), 16);
        int startGreen = Integer.parseInt(startColor.substring(3, 5), 16);
        int startBlue = Integer.parseInt(startColor.substring(5, 7), 16);

        int endRed = Integer.parseInt(endColor.substring(1, 3), 16);
        int endGreen = Integer.parseInt(endColor.substring(3, 5), 16);
        int endBlue = Integer.parseInt(endColor.substring(5, 7), 16);

        // 将初始化颜色的值定义为当前需要操作的颜色值
            mCurrentRed = startRed;
            mCurrentGreen = startGreen;
            mCurrentBlue = startBlue;


        // 计算初始颜色和结束颜色之间的差值
        // 该差值决定着颜色变化的快慢:初始颜色值和结束颜色值很相近,那么颜色变化就会比较缓慢;否则,变化则很快
        // 具体如何根据差值来决定颜色变化快慢的逻辑写在getCurrentColor()里.
        int redDiff = Math.abs(startRed - endRed);
        int greenDiff = Math.abs(startGreen - endGreen);
        int blueDiff = Math.abs(startBlue - endBlue);
        int colorDiff = redDiff + greenDiff + blueDiff;
        if (mCurrentRed != endRed) {
            mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0,
                    fraction);
                    // getCurrentColor()决定如何根据差值来决定颜色变化的快慢 ->>关注1
        } else if (mCurrentGreen != endGreen) {
            mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff,
                    redDiff, fraction);
        } else if (mCurrentBlue != endBlue) {
            mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff,
                    redDiff + greenDiff, fraction);
        }
        // 将计算出的当前颜色的值组装返回
        String currentColor = "#" + getHexString(mCurrentRed)
                + getHexString(mCurrentGreen) + getHexString(mCurrentBlue);

        // 由于我们计算出的颜色是十进制数字,所以需要转换成十六进制字符串:调用getHexString()->>关注2
        // 最终将RGB颜色拼装起来,并作为最终的结果返回
        return currentColor;
    }


    // 关注1:getCurrentColor()
    // 具体是根据fraction值来计算当前的颜色。

    private int getCurrentColor(int startColor, int endColor, int colorDiff,
                                int offset, float fraction) {
        int currentColor;
        if (startColor > endColor) {
            currentColor = (int) (startColor - (fraction * colorDiff - offset));
            if (currentColor < endColor) {
                currentColor = endColor;
            }
        } else {
            currentColor = (int) (startColor + (fraction * colorDiff - offset));
            if (currentColor > endColor) {
                currentColor = endColor;
            }
        }
        return currentColor;
    }

    // 关注2:将10进制颜色值转换成16进制。
    private String getHexString(int value) {
        String hexString = Integer.toHexString(value);
        if (hexString.length() == 1) {
            hexString = "0" + hexString;
        }
        return hexString;
    }

}
  • 第四步 调用ObjectAnimtor.ofObject();设置动画
  ObjectAnimator myView1Animator=ObjectAnimator.ofObject(myView1,"color",new ColorEvaluator(),"#00ff00","#ffffaa");
                myView1Animator.setDuration(3000);
                myView1Animator.start();

这样一个自定义对象的动画就完成了

球体颜色渐变

2.2.1 注意事项

  1. 假如对象必须要提供属性a的set()方法
 1)假如你没有给初始值,既ObjectAnimtor.ofObject()的最后一个可变的参数你只给了一个值,其实就是结束的值,这个时候系统会调用get方法,去获取默认值,然后动画就是从默认值开始做动画的,如果没有给get方法这个时候程序会直接爆炸,但是如果你给了  两个货两个以上的值那么get方法就可有可无,(建议写上避免不必要的麻烦),
 2)加入你的可变参数只传入一个值,即使你写了get方法,但是如果你的默认值不合法,那么程序也会崩溃,如上面小球的例子,颜色定义成了String 类型,如果你的默认值不是#000000这样的格式,下面转换的时候不能够正确的转换也会崩溃,请注意这两点
 3) 如果你没有提供set方法,那么你直接调用ObjectAnimtor.ofObject(),程序不会崩溃,但是达不到动画的效果,会没有任何的反应

2.3.1 上面介绍了一个继承原生的View对自定义View做了一个颜色渐变的操作, 下面这个介绍一个用封装,做出对对象做动画

例如我们要改变一个(View的宽度),我们调用setWindth();方法是没有效果的,因为View虽然有这样的get() set() 方法,但是实际却不是用来改变控件的宽度的,而是设置该View的 最大最小宽度

这里直接给列子


 class FengWindth {
        int currentWindth;
        View mView;
        public FengWindth(View view){
            this.mView=view;
        }
        public int getWindth() {
            return mView.getLayoutParams().width;
        }
        public void setWindth(int windth) {
            this.currentWindth=windth;
            ViewGroup.LayoutParams params = mView.getLayoutParams();
            params.width=windth;
//            mView.requestLayout();
            mView.setLayoutParams(params);
        }
    }

使用:


ObjectAnimator obgWindth = ObjectAnimator.ofInt(new FengWindth(btn_windth), "windth", 300,600);
                obgWindth.setDuration(2000).start();

通过封装,给View添加上setWidth()的方法

3 组合动画(AnimatorSet 类)

3.1.1介绍

AnimatorSet 可以吧多个动画,平移,旋转,缩放,当人也包括自定义的等动画结合在一起,
可以控制,同时播放,顺序播放,延时播放,或者在某个动画之后播放等:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值