欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 属性动画

程序员文章站 2022-04-09 14:51:25
一、ValueAnimator ValueAnimator是值的变动,可以控制控件的一些值,从而达到变化动画的效果。 监听器三个 移除监听器 当移除监听器时,正在执行的动画不会受到影响,但是之后再执行动画,动画的监听效果将不会再呈现。 不常用函数 常用函数 效果: 二、自定义插值器 1.插值器的理解 ......

一、valueanimator

valueanimator是值的变动,可以控制控件的一些值,从而达到变化动画的效果。

    public void doanimation() {
//        final valueanimator valueanimatorint = valueanimator.ofint(0,400,100,555,250);
        //输入需要变化的值,是个变化的数组,可以有int类型和float类型
        final valueanimator valueanimator = valueanimator.offloat(0.0f,400.0f,100.0f,555.0f,250.0f);
        valueanimator.setduration(9000);//动画持续时间
        //监听动画的变化时间,在变化中对控件进行操作,也可以通过handle来做一些有趣的事情
        valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
            @override
            public void onanimationupdate(valueanimator animation) {
                //获得变化的值
                float curvaluefloat = (float) valueanimator.getanimatedvalue();
                //设置为整型
                int curvalue = curvaluefloat.intvalue();
                //改变控件的位置,layout对应的是控件的位置
                valuetv.layout(curvalue, curvalue, curvalue + imageview.getwidth(), curvalue + imageview.getheight());
            }
        });
        valueanimator.start();
    }

监听器三个
Android 属性动画

        //监听1
        valueanimator.addpauselistener(new animator.animatorpauselistener() {
            @override
            public void onanimationpause(animator animation) {
                //暂停
            }

            @override
            public void onanimationresume(animator animation) {
                //运行
            }
        });

        //监听2
        valueanimator.addlistener(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) {
                //循环一次
            }
        });

        //监听3
        valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
            @override
            public void onanimationupdate(valueanimator animation) {
                //数值更新
            }
        });

移除监听器
当移除监听器时,正在执行的动画不会受到影响,但是之后再执行动画,动画的监听效果将不会再呈现。

/** 
 * 移除animatorupdatelistener 
 */  
void removeupdatelistener(animatorupdatelistener listener);  
void removeallupdatelisteners();  

 /** 
  * 移除animatorlistener 
  */  
void removelistener(animatorlistener listener);  
void removealllisteners();

不常用函数

/**
 * 延时多久时间开始,单位是毫秒
 */
public void setstartdelay(long startdelay)
    
/**
 * 完全克隆一个valueanimator实例,包括它所有的设置以及所有对监听器代码的处理
 */
public valueanimator clone()

常用函数

/**
 * 设置动画时长,单位是毫秒
 */
valueanimator setduration(long duration)
    
/**
 * 获取valueanimator在运动时,当前运动点的值
 */
object getanimatedvalue();

/**
 * 开始动画
 */
void start()
    
/**
 * 设置循环次数,设置为infinite表示无限循环
 */
void setrepeatcount(int value)
    
/**
 * 设置循环模式
 * value取值有restart,reverse,
 */
void setrepeatmode(int value)
    
/**
 * 取消动画
 */
void cancel()

效果:

Android 属性动画

二、自定义插值器

1.插值器的理解

首先看看自动自定义的插值器
匀速插值器:
看看继承关系:linearinterpolator---继承--->baseinterpolator---继承--->interpolator---实现-->timeinterpolator
最后看看timeinterpolator都写了啥:
只定义了一个getinterpolation(float input)方法。

package android.animation;

/**
 * a time interpolator defines the rate of change of an animation. this allows animations
 * to have non-linear motion, such as acceleration and deceleration.
 */
public interface timeinterpolator {

    /**
     * maps a value representing the elapsed fraction of an animation to a value that represents
     * the interpolated fraction. this interpolated value is then multiplied by the change in
     * value of an animation to derive the animated value at the current elapsed animation time.
     *
     * @param input a value between 0 and 1.0 indicating our current point
     *        in the animation where 0 represents the start and 1.0 represents
     *        the end
     * @return the interpolation value. this value can be more than 1.0 for
     *         interpolators which overshoot their targets, or less than 0 for
     *         interpolators that undershoot their targets.
     */
    float getinterpolation(float input);
}

linearinterpolator的定义

public class linearinterpolator extends baseinterpolator implements nativeinterpolatorfactory {

    public linearinterpolator() {
    }

    public linearinterpolator(context context, attributeset attrs) {
    }

    public float getinterpolation(float input) {
        return input; //数值进度与时间同步
    }

    /** @hide */
    @override
    public long createnativeinterpolator() {
        return nativeinterpolatorfactoryhelper.createlinearinterpolator();
    }
}

accelerateinterpolator开始慢,后面一直加速插值器,也叫幂函数插值器,核心方法

 public float getinterpolation(float input) {
        if (mfactor == 1.0f) {
            return input * input;
        } else {
            //返回的是时间的次幂数,比如 input=3,mdoublefactor=2,
            //那么返回的就是,3的2次方,就是9
            //所以会按照几何倍增,这是一个幂函数
            return (float)math.pow(input, mdoublefactor); 
        }
    }

所有的速度都离不开这个方法:getinterpolation

而最为关键的就是input这个数字。以下是经典解释:

input参数代表了当前动画的进度,而返回值则代表了当前动画的数值进度。

上面的匀速,返回的就是时间的值,所以,动画进度和动画的数值持平。
幂函数的时候,随着动画进度的增加,动画的数值进度也就越来越大,从而一直加速。

input的取值范围是0~1之间,返回值可以超过1,也可以小于0,超过1表示已经超过目标位置,小于0表示远离初始位置。

简单的公式就是

y= -> x

y代表返回的值,也就是动画需要的数值进度,x代表时间进度,->则是通过一些数学手段,来得到想要的y值。

  • 当一些动画定义这些插值器的时候,返回的数值进度越大,速度越快。比如你在匀速运动的时候,时间进度是0.5s,数值进度也是0.5,那就是匀速运动。

2.定义一个简单的插值器

我们用数学中的定义来做一个插值器。
y=1-x
把进度反过来,当进度传入0的时候,数值进度已经在目标位置了。当传入1时,数值则在刚开始的位置。

  class fiveinterpolator implements timeinterpolator {

        @override
        public float getinterpolation(float input) {
            return 1-input;
        }
    }

valueanimator.setinterpolator(``new ``fiveinterpolator())``;
一个简单的自定义插值器就完成了。

三、evaluator

  • evaluator是数值转换器,就是将数值进度转化为具体的数值。
  • 就是0~400的数值变换,当数值进度是50%的时候,那通过evaluator来转换,就变成了200
  • oflnt()函 数对应 evauator 类名为 intevauaor ,而 offloat()函数对应的 evauator 类名为 floatevaluator

自定义数值转换器:

 	//自定义数值转换器
    class myfloatevaluator implements typeevaluator<float>{

        /**
         * @param fraction 代表数值进度的值,就是上面getinterpolation()的返回值
         * @param startvalue  代表offloat(float startvalue,float endvalue)
         * @param endvalue
         * */
        @override
        public float evaluate(float fraction, float startvalue, float endvalue) {
            //初始值
            float startfloat=startvalue;

            //当前值=初始值+总值*进度
            float inputvalue=startfloat+(endvalue-startfloat)*fraction;
            return inputvalue;
        }
    }

使用:

valueanimator.setevaluator(new myfloatevaluator());

所以可以通过插值器和数值转化器来改变控件的数值变化

valueanimator.setinterpolator(new fiveinterpolator());
valueanimator.setevaluator(new myfloatevaluator());

四、argbevaluator

argbevaluator可以把颜色转换过渡。
具体实现:

 //颜色的数值变换
    public void docoloranimation(){
        valueanimator valueanimator=valueanimator.ofint(0xffffff00,0xff0000ff);
        valueanimator.setevaluator(new argbevaluator());
        valueanimator.setduration(3000);
        valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
            @override
            public void onanimationupdate(valueanimator animation) {
                int curvalue=(int)animation.getanimatedvalue();
                valuetv.setbackgroundcolor(curvalue);
            }
        });
        valueanimator.start();
    }

效果:

Android 属性动画

颜色必须包含argb四个值。
Android 属性动画

五、valueanimation-ofobject

首先看看这个方法是如何传值的。

public static valueanimator ofobject(typeevaluator evaluator, object... values) {
        valueanimator anim = new valueanimator();
        anim.setobjectvalues(values);
        anim.setevaluator(evaluator);
        return anim;
    }

typeevaluator evaluator需要传入自定义的数值转换器
object... values 可变长参数

实例
实现一个字母从a到z的过程

public void doobjectvalue() {
        valueanimator valueanimator = valueanimator.ofobject(new charinterpolator(), new character('a'), new character('z'));
        valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
            @override
            public void onanimationupdate(valueanimator animation) {
                char str = (char) animation.getanimatedvalue();
                valuetv.settext(string.valueof(str));
            }
        });
        valueanimator.setduration(7000);
        valueanimator.setinterpolator(new accelerateinterpolator());
        valueanimator.start();
    }

    class charinterpolator implements typeevaluator<character> {

        @override
        public character evaluate(float fraction, character startvalue, character endvalue) {
            int startint = (int) startvalue;  //ascii转换   a代表56 以此递增
            int endint = (int) endvalue;
            int curint = (int) (startint + fraction * (endint - startint));
            char result = (char) curint;
            return result;
        }
    }

效果:

Android 属性动画

六、objectanimator

objeceanimation--继承--->valueanimation
与控件之间相关联,从监听动画中解放出来。
先看看这个方法:

objectanimator offloat(object target, string propertyname, float... values)

具体使用

  public void doobjectanimationbyalpha(){
        objectanimator objectanimator=objectanimator.offloat(valuetv,"alpha",1,0,1);
        objectanimator.setduration(6000);
        objectanimator.start();
    }

object target要控制的控件
string propertyname要改变的动画效果
float... values传入的具体变化值
具体效果就是跟视图动画中设置的动画是一样的效果,透明度从1到0再到1.
“alpha”中,是对应view中的setalpha()方法,后面的可变成参数就是可以传入具体是变换数值。
看看view中有多少个set函数:

透明度:alpha

setalpha(@floatrange(from=0.0, to=1.0) float alpha)  //透明度

旋转角度:rotation,rotationx,rotationy

setrotation(float rotation) //围绕z轴旋转,z轴指的是垂直屏幕的方向
setrotationx(float rotationx)  //围绕x轴旋转
setrotationy(float rotationy)  //围绕y轴旋转

平移:translationx,translationy

settranslationx(float translationx)   //x轴屏幕,右为正方向,当前控件为原点
settranslationy(float translationy)

缩放:scalex,scaley

setscalex(float scalex) //x轴缩放
setscaley(float scaley)

看看旋转是三个效果:

 public void doobjectanimationbyalpha(){
        objectanimator objectanimator=objectanimator.offloat(valuetv,"rotationy",360);
        objectanimator.setduration(6000);
        objectanimator.start();
    }

z轴:

Android 属性动画

x轴:

Android 属性动画

y轴:

Android 属性动画

七、自定义objectanimator

因为objectanimator是通过set来反射实现的,所以自己也可以通过这样的操作来实现自己view的set函数,从而实现简单的动画效果。

1.自定义view的set函数

fallingballimageview.java

public class fallingballimageview extends imageview {
    public fallingballimageview(context context, @nullable attributeset attrs) {
        super(context, attrs);
    }

    public void setfallingpos(point pos){
        layout(pos.x,pos.y,pos.x+getwidth(),pos.y+getheight());
    }

}

布局使用

<com.lanjiabin.systemtest.anim.fallingballimageview
                android:id="@+id/imageball"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margintop="30dp"
                android:background="@drawable/shape"
                android:layout_marginbottom="25dp" />

set函数的名字是setfallingpos,所以在传递反射函数名字的时候,应该是fallingpos或者fallingpos,必须是这两个名字中其中一个的格式,否则就不会正确反射。参数类型是point,所以使用函数是ofobject()

2.自定义evaluator

 class divevaluator implements typeevaluator<point> {
        point point = new point();

        @override
        public point evaluate(float fraction, point startvalue, point endvalue) {
            point.x = (int) (startvalue.x + (endvalue.x - startvalue.x) * fraction);
            if (fraction * 2 <= 1) {
                point.y = (int) (startvalue.y + (endvalue.y - startvalue.y) * fraction);
            } else {
                point.y = endvalue.y;
            }
            return point;
        }
    }

3.实现最终反射调用

  public void doobjectanimationbydiv() {
        objectanimator objectanimator=objectanimator
                .ofobject(
                        ballimageview,  //自定义view的小球
                        "fallingpos",   //反射名字,fallingpos或者fallingpos都可以
                        new divevaluator(), //自定义转换器
                        new point(0,0),     //起始坐标
                        new point(300,300)); //目标坐标
        objectanimator.setduration(4000);   //动画时长
        objectanimator.start();
    }

4.效果

Android 属性动画

5.get函数

当我们在上述函数的时候,ofobject()传的都是可变长的参数,也就是两个参数以上,当我们只传递一个参数的时候,这个参数只是目标参数,没有初始参数,系统就会默认调用系统自带的get方法,来获得初始值。当没有这个get方法的时候,就会报错,以至于崩溃。
所以想传递一个参数,就需要自定义get()方法,返回的,就是初始值。对应名字也和set的名字类似。
setfallingpos(point pos)的名字就是getfallingpos(point pos)

在自定义view中加入get方法:返回控件的初始point

 public point getfallingpos() {
        int[] location = new int[2];
        this.getlocationonscreen(location);
        return new point(location[0], location[1]);
    }

八、animatorset

1.animatorset理解和使用

animatorset组合动画,对valueanimation和objectanimation都有一样的效果。
有两个播放方法:只管播放的时间,不管动画个体是如何操作的,不管动画的执行时间,循环次数等。
playsequentially()
是顺序播放,当前一个动画播放完毕以后,才会执行下一个动画。当前一个动画是无限循环时,后一个动画也就无法播放。有两个构造方法。

playsequentially(animator... items)
playsequentially(list<animator> items)

playtogether()
是一起播放,同一个时间内,在列表中所有动画同一时间启动。

playtogether(animator... items)
playtogether(collection<animator> items)

具体实例,有一个缩放动画和位移动画,分别实现同时播放和顺序播放。

 public void doanimationset() {
        //缩放
        objectanimator objectanimatorscaley = objectanimator.offloat(ballimageview, "scaley", 0.0f, 1.6f, 1.0f);

        //平移
        objectanimator objectanimatortranslationx = objectanimator.offloat(ballimageview, "translationx", 400);

        //组合动画
        animatorset animator = new animatorset();

        //每个动画的播放时间
        animator.setduration(3000);

        //顺序播放
        animator.playsequentially(objectanimatorscaley, objectanimatortranslationx);

        //一起播放
        animator.playtogether(objectanimatorscaley, objectanimatortranslationx);

        animator.start();
    }

同时播放:动画效果同时体现出来,缩放和位移
Android 属性动画

顺序播放:先缩放完毕再位移
Android 属性动画

2.animatorset.builder

  		//组合动画
        animatorset animator = new animatorset();

        //目标动画
        animatorset.builder builder=animator.play(objectanimatorscaley);

        //执行目标动画后再执行该动画
        builder.after(objectanimatorscaley);

        //执行该动画后再执行目标动画
        builder.before(objectanimatorscaley);

        //和目标动画一起播放
        builder.with(objectanimatorscaley);

        //延迟时间执行目标动画
        builder.after(3000);


		//串行方式
        animatorset animator = new animatorset();
        animatorset.builder builder=animator
        	.play(objectanimatorscaley)
            .after(objectanimatorscaley)
            .before(objectanimatorscaley);


		//如果animatorset设置了动画时长,循环次数等,都以animatorset为准,单个设置不起作用。
        //每个动画的播放时间
        animator.setduration(3000);
  		//所有的动画都集中于这个控件上,其它的不起作用
        animator.settarget(ballimageview);

九、实例-卫星菜单

1.实现原理

实现一个放射卫星的效果,点击一下,放射出菜单,再点击一下,收回菜单。
原理就是,将所有的菜单重叠在一起,点击最上面的菜单,按照不同的角度,实现位移,缩放,透明度的效果,将下面的菜单都位移出去。看看位移的计算方式,每个菜单,与主菜单都形成了直角形式,水平x轴的位移和y轴的水平位移都可以计算出来。  就是从主菜单,位移到不同位置的x轴和y轴。
Android 属性动画

2.布局

布局非常简单,全部控件叠加在一起,而且子菜单的属性全部一致,省略了一些重复的空间。

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <framelayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margintop="20dp">

        <!-- shadow 代表阴影,对阴影的一些处理-->
        <button
            android:id="@+id/mainbtn"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center_vertical|right"
            android:layout_marginright="40dp"
            android:background="@drawable/menu_main"
            android:outlineambientshadowcolor="@android:color/transparent"
            android:outlinespotshadowcolor="@android:color/transparent"
            android:shadowcolor="@android:color/transparent" />

        <button
            android:id="@+id/rockbtn"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center_vertical|right"
            android:layout_marginright="20dp"
            android:background="@drawable/menu_rock"
            android:outlineambientshadowcolor="@android:color/transparent"
            android:outlinespotshadowcolor="@android:color/transparent"
            android:shadowcolor="@android:color/transparent"
            android:visibility="gone" />
                
            <!-- 以下省略六个子按钮菜单 -->    
    </framelayout>


</linearlayout>

3.java代码

核心思想就是,添加要控制的子菜单,开启动画方法,关闭动画方法。

public class exampleactivity extends baseactivity {

    private boolean mismenuopen = false;
    private button mmainbtn, mrockbtn, mairbtn, mtrainbtn, mcarbtn, mmotorbikebtn, mbicyclebtn, mwalkbtn;
    list<button> mbtnarray;

    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        initview();
        onclick();
    }

    public void initview() {
        setcontentview(r.layout.activity_example);
        mmainbtn = findviewbyid(r.id.mainbtn);

        mrockbtn = findviewbyid(r.id.rockbtn);
        mairbtn = findviewbyid(r.id.airbtn);
        mtrainbtn = findviewbyid(r.id.trainbtn);
        mcarbtn = findviewbyid(r.id.carbtn);
        mmotorbikebtn = findviewbyid(r.id.motorbikebtn);
        mbicyclebtn = findviewbyid(r.id.bicyclebtn);
        mwalkbtn = findviewbyid(r.id.walkbtn);

        //添加子菜单
        mbtnarray = new arraylist<button>();
        mbtnarray.add(mrockbtn);
        mbtnarray.add(mairbtn);
        mbtnarray.add(mtrainbtn);
        mbtnarray.add(mcarbtn);
        mbtnarray.add(mmotorbikebtn);
        mbtnarray.add(mbicyclebtn);
        mbtnarray.add(mwalkbtn);
    }

    public void onclick() {
        mmainbtn.setonclicklistener(new view.onclicklistener() {
            @override
            public void onclick(view v) {
                switchanimation();
            }
        });

        mrockbtn.setonclicklistener(new view.onclicklistener() {
            @override
            public void onclick(view v) {
                toast.maketext(exampleactivity.this, "你选择了火箭出行!", toast.length_short).show();
            }
        });
    }

    //开关
    public void switchanimation() {
        if (!mismenuopen) {
            mismenuopen = true;
            for (int i = 0; i < mbtnarray.size(); i++) {
                doanimationopen(mbtnarray.get(i), i, mbtnarray.size(), 500);
            }
        } else {
            mismenuopen = false;
            for (int i = 0; i < mbtnarray.size(); i++) {
                doanimationclose(mbtnarray.get(i), i, mbtnarray.size(), 500);
            }
        }
    }

    /**
     * 开启动画/展开菜单
     * @param view   要控制的控件/子菜单
     * @param index  要控制控件的顺序
     * @param total  子菜单的总数
     * @param radius 主菜单到子菜单的距离/半径
     * */
    private void doanimationopen(view view, int index, int total, int radius) {

        //显示菜单
        if (view.getvisibility() != view.visible) {
            view.setvisibility(view.visible);
        }

        //计算每个菜单的角度,toradians()将度数转换为弧度
        //七个子菜单,有六个夹角角,180/(7-1)*2  2代表第二个夹角
        double degree = math.toradians(180) / (total - 1) * index;

        //x轴位移
        int translationx = -(int) (radius * math.sin(degree));

        //y轴位移
        int translationy = -(int) (radius * math.cos(degree));
        animatorset animatorset = new animatorset();

        //动画合集
        animatorset.playtogether(

                //从原来控件的位置往x轴移动多少
                objectanimator.offloat(view, "translationx", 0, translationx),

                //从原来控件的位置往y轴移动多少
                objectanimator.offloat(view, "translationy", 0, translationy),

                //x轴缩放
                objectanimator.offloat(view, "scalex", 0.01f, 1f),

                //y轴缩放
                objectanimator.offloat(view, "scaley", 0.01f, 1.0f),

                //透明度
                objectanimator.offloat(view, "alpha", 0.01f, 1.0f)
        );
        animatorset.setduration(500);
        animatorset.start();
    }

    //关闭菜单/动画
    private void doanimationclose(view view, int index, int total, int radius) {
        if (view.getvisibility() != view.visible) {
            view.setvisibility(view.visible);
        }
        double degree = math.toradians(180) / (total - 1) * index;
        int translationx = -(int) (radius * math.sin(degree));
        int translationy = -(int) (radius * math.cos(degree));
        animatorset animatorset = new animatorset();

        animatorset.playtogether(
                objectanimator.offloat(view, "translationx", translationx, 0),
                objectanimator.offloat(view, "translationy", translationy, 0),
                objectanimator.offloat(view, "scalex", 1.0f, 0.01f),
                objectanimator.offloat(view, "scaley", 1.0f, 0.01f),
                objectanimator.offloat(view, "alpha", 1.0f, 0.01f)
        );
        animatorset.setduration(500);
        animatorset.start();
    }
}

3.效果

Android 属性动画

十、xml实现animator

1.animator

在animator下建立animator.xml

Android 属性动画

xml代码:

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:valuefrom="0"
    android:valueto="300"
    android:valuetype="inttype" />

java代码使用

  valueanimator valueanimator=(valueanimator)animatorinflater.loadanimator(
                                exampleactivity.this,
                                r.animator.animator);

                valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
                    @override
                    public void onanimationupdate(valueanimator animation) {
                        int offset=(int)animation.getanimatedvalue();
                        mrockbtn.layout(offset,offset,mrockbtn.getwidth()+offset,mrockbtn.getheight()+offset);
                    }
                });
                valueanimator.start();

2.objectanimator

object_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectanimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"  //时间
    android:interpolator="@android:anim/accelerate_interpolator"  //插值器
    android:propertyname="string"  //要映射的名字
    android:repeatcount="11"      //循环次数
    android:repeatmode="restart"  //循环模式
    android:startoffset="777"     
    android:valuefrom="99"  //开始
    android:valueto="199"   //目标
    android:valuetype="inttype"  //数据类型
    />

java代码使用

  objectanimator animator=(objectanimator)animatorinflater.loadanimator(
                        exampleactivity.this,
                        r.animator.object_animator);
                animator.settarget(mairbtn);
                animator.start();

十一、后语

包括其它的知识点,都只能说一些基础的内容,很多方法和拓展知识都没有说道,需要自己去探索,多阅读sdk源码。属性动画,有一些高级的内容,后续会持续拓展。

编程中我们会遇到多少挫折?表放弃,沙漠尽头必是绿洲。