自己定义控件三部曲之动画篇(七)——ObjectAnimator基本使用
前言:
假如生活欺骗了你,
不要悲伤,不要心急!
忧郁的日子里须要镇静:
相信吧,快乐的日子终将会来临!
心儿永远向往着未来;
如今却常是忧郁。
一切都是瞬息,一切都将会过去;
而那过去了的,就会成为亲切的怀恋。
—–普希金
相关文章:
《Android自己定义控件三部曲文章索引》:http://blog.csdn.net/harvic880925/article/details/50995268
一、概述
1、引入
上几篇给大家讲了ValueAnimator。但ValueAnimator有个缺点。就是仅仅能对数值对动画计算。我们要想对哪个控件操作。须要监听动画过程,在监听中对控件操作。这样使用起来相比补间动画而言就相对照较麻烦。
为了能让动画直接与相应控件相关联,以使我们从监听动画过程中解放出来,谷歌的开发者在ValueAnimator的基础上,又派生了一个类ObjectAnimator;
因为ObjectAnimator是派生自ValueAnimator的。所以ValueAnimator中所能使用的方法,在ObjectAnimator中都能够正常使用。
但ObjectAnimator也重写了几个方法,比方ofInt(),ofFloat()等。我们先看看利用ObjectAnimator重写的ofFloat方法怎样实现一个动画:(改变透明度)
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"alpha",1,0,1);
animator.setDuration(2000);
animator.start();
效果图例如以下:
我们这里还是直接使用上一篇的框架代码;(当点击start anim时运行动画)从上面的代码中能够看到构造ObjectAnimator的方法非常简单:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
- 第一个參数用于指定这个动画要操作的是哪个控件
- 第二个參数用于指定这个动画要操作这个控件的哪个属性
- 第三个參数是可变长參数。这个就跟ValueAnimator中的可变长參数的意义一样了。就是指这个属性值是从哪变到哪。像我们上面的代码中指定的就是将textview的alpha属性从0变到1再变到0;
以下我们再来看一下怎样实现旋转效果:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);
animator.setDuration(2000);
animator.start();
效果图例如以下:
从代码中能够看到,我们仅仅须要改变ofFloat()的第二个參数的值就能够实现相应的动画;
那么问题来了,我们怎么知道第二个參数的值是啥呢?
2、setter函数
我们再回来看构造改变rotation值的ObjectAnimator的方法
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);
TextView控件有rotation这个属性吗?没有,不光TextView没有,连它的父类View中也没有这个属性。那它是怎么来改变这个值的呢?事实上,ObjectAnimator做动画,并非依据控件xml中的属性来改变的,而是通过指定属性所相应的set方法来改变的。比方,我们上面指定的改变rotation的属性值。ObjectAnimator在做动画时就会到指定控件(TextView)中去找相应的setRotation()方法来改变控件中相应的值。相同的道理,当我们在最開始的演示样例代码中,指定改变”alpha”属性值的时候,ObjectAnimator也会到TextView中去找相应的setAlpha()方法。那TextView中都有这些方法吗,有的。这些方法都是从View中继承过来的,在View中有关动画。总共同拥有以下几组set方法:
//1、透明度:alpha
public void setAlpha(float alpha) //2、旋转度数:rotation、rotationX、rotationY
public void setRotation(float rotation)
public void setRotationX(float rotationX)
public void setRotationY(float rotationY) //3、平移:translationX、translationY
public void setTranslationX(float translationX)
public void setTranslationY(float translationY) //缩放:scaleX、scaleY
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)
能够看到在View中已经实现了有关alpha,rotaion,translate,scale相关的set方法。所以我们在构造ObjectAnimator时能够直接使用。
在開始逐个看这些函数的使用方法前。我们先做一个总结:
1、要使用ObjectAnimator来构造对画,要操作的控件中。必须存在相应的属性的set方法
2、setter 方法的命名必须以骆驼拼写法命名。即set后每一个单词首字母大写,其余字母小写,即相似于setPropertyName所相应的属性为propertyName
以下我们就来看一下上面中各个方法的使用方法及作用。
有关alpha的使用方法。上面已经讲过了,以下我们来看看其他的
(1)、setRotationX、setRotationY与setRotation
- setRotationX(float rotationX):表示环绕X轴旋转,rotationX表示旋转度数
- setRotationY(rotationY):表示环绕Y轴旋转,rotationY表示旋转度数
- setRotation(float rotation):表示环绕Z旋转,rotation表示旋转度数
先来看看setRotationX的效果:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationX",0,270,0);
animator.setDuration(2000);
animator.start();
效果图例如以下:
从效果图中明显看出,textview的旋转方法是环绕X轴旋转的,我们设定为从0度旋转到270度再返回0度。
然后再来看看setRotationY的使用方法与效果:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationY",0,180,0);
animator.setDuration(2000);
animator.start();
效果图例如以下:
从效果图中明显能够看出环绕Y轴旋转的。
我们再来看看setRotation的使用方法与效果:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,270,0);
animator.setDuration(2000);
animator.start();
我们上面说了,setRotation是环绕Z轴旋转的,可能有些同学不理解什么是Z轴,我们来看一张图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
从这张图中,绿色框部分表示手机屏幕,非常明显能够看出Z轴就是从屏幕左上角原点向外伸出的一条轴。
这样。我们也就能够理解环绕Z轴旋转。为什么是这样子转了。
(2)、setTranslationX与setTranslationY
- setTranslationX(float translationX) :表示在X轴上的平移距离,以当前控件为原点,向右为正方向。參数translationX表示移动的距离。
- setTranslationY(float translationY) :表示在Y轴上的平移距离。以当前控件为原点。向下为正方向,參数translationY表示移动的距离。
我们先看看setTranslationX的使用方法:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationX", 0, 200, -200,0);
animator.setDuration(2000);
animator.start();
效果图例如以下:
所以。我们上面在构造动画时,指定的移动距离是(0, 200, -200,0)。所以控件会从自身全部位置向右移动200像素,然后再移动到距离原点-200的位置,最后回到原点。
然后我们来看看setTranslateY的使用方法:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationY", 0, 200, -100,0);
animator.setDuration(2000);
animator.start();
效果图例如以下:(为了方便看到效果。将textview垂直居中)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
相同,移动位置的坐标也都是以当前控件所在位置为中心点的。所以相应的移动位置从原点移动向下移动200像素,然后再移动到向下到距原点200像素的位置,最后再回到(0,0)从效果图中非常明显能够看出来。
从上面能够看出:每次移动距离的计算都是以原点为中心的;比方初始动画为ObjectAnimator.ofFloat(tv, “translationY”, 0, 200, -100,0)表示首先从0移动到正方向200的位置,然后再移动到负方向100的位置。最后移动到原点。
(3)、setScaleX与setScaleY
- setScaleX(float scaleX):在X轴上缩放。scaleX表示缩放倍数
- setScaleY(float scaleY):在Y轴上缩放,scaleY表示缩放倍数
我们来看看setScaleX的使用方法:
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleX", 0, 3, 1);
animator.setDuration(2000);
animator.start();
效果图例如以下:
在效果图中,从0倍放大到3倍,然后再还原到1倍的原始状态。
然后再来看看setScaleY的使用方法
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleY", 0, 3, 1);
animator.setDuration(2000);
animator.start();
为了更好的看到效果,我把textview垂直居中了,效果图例如以下:
好了,到这里有关View中自带的set函数讲完了,我们来看看ObjectAnimator是怎样实现控件动画效果的。
3、ObjectAnimator动画原理
我们先来看张图:
在这张图中,将ValueAnimator的动画流程与ObjectAnimator的动画流程做了个对照。
能够看到ObjectAnimator的动画流程中,也是首先通过加速器产生当前进度的百分比。然后再经过Evaluator生成相应百分比所相应的数字值。这两步与ValueAnimator是全然一样的,唯一不同的是最后一步。在ValueAnimator中,我们要通过加入监听器来监听当前数字值。而在ObjectAnimator中,则是先依据属性值拼装成相应的set函数的名字,比方这里的scaleY的拼装方法就是将属性的第一个字母强制大写后,与set拼接,所以就是setScaleY。然后通过反射找到相应控件的setScaleY(float scaleY)函数,将当前数字值做为setScaleY(float scale)的參数将其传入。
这里在找到控件的set函数以后。是通过反射来调用这个函数的,有关反射的使用大家能够參考《夯实JAVA基本之二 —— 反射(1):基本类周边信息获取》
这就是ObjectAnimator的流程,最后一步总结起来就是调用相应属性的set方法。将动画当前数字值做为參数传进去。
依据上面的流程,这里有几个注意事项:
(1)、拼接set函数的方法:上面我们也说了是首先是强制将属性的第一个字母大写,然后与set拼接,就是相应的set函数的名字。
注意。仅仅是强制将属性的第一个字母大写,后面的部分是保持不变的。
反过来,假设我们的函数名命名为setScalePointX(float ),那我们在写属性时能够写成”scalePointX”或者写成“ScalePointX”都是能够的,即第一个字母大写和小写能够任意。但后面的部分必须与set方法后的大写和小写保持一致。
(2)、怎样确定函数的參数类型:上面我们知道了怎样找到相应的函数名,那相应的參数方法的參数类型怎样确定呢?我们在讲ValueAnimator的时候说过。动画过程中产生的数字值与构造时传入的值类型是一样的。因为ObjectAnimator与ValueAnimator在插值器和Evaluator这两步是全然一样的。而当前动画数值的产生是在Evaluator这一步产生的,所以ObjectAnimator的动画中产生的数值类型也是与构造时的类型一样的。那么问题来了,像我们的构造方法。
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleY", 0, 3, 1);
因为构造时使用的是ofFloat函数,所以中间值的类型应该是Float类型的,所以在最后一步拼装出来的set函数应该是setScaleY(float xxx)的样式;这时,系统就会利用反射来找到setScaleY(float xxx)函数,并把当前的动画数值做为參数传进去。
那问题来了。假设没有相似setScaleY(float xxx)的函数,我们仅仅实现了一个setScaleY(int xxx)的函数怎么办?这里尽管函数名一样。但參数类型是不一样的。那么系统就会报一个错误:
意思就是相应函数的指定參数类型没有找到。
(3)、调用set函数以后怎么办?从ObjectAnimator的流程能够看到。ObjectAnimator仅仅负责把动画过程中的数值传到相应属性的set函数中就结束了。注意传给set函数以后就结束了。set函数就相当我们在ValueAnimator中加入的监听的作用,set函数中的对控件的操作还是须要我们自己来写的。
那我们来看看View中的setScaleY是怎么实现的吧:
/**
* Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
* the view's unscaled width. A value of 1 means that no scaling is applied.
*
* @param scaleY The scaling factor.
* @see #getPivotX()
* @see #getPivotY()
*
* @attr ref android.R.styleable#View_scaleY
*/
public void setScaleY(float scaleY) {
ensureTransformationInfo();
final TransformationInfo info = mTransformationInfo;
if (info.mScaleY != scaleY) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
info.mScaleY = scaleY;
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
}
大家不必理解这一坨代码的意义,因为这些代码是须要读懂View的总体流程以后才干看得懂的。仅仅须要跟着我的步骤来理解即可。这段代码总共分为两部分:第一步又一次设置当前控件的參数,第二步调用Invalidate()强制重绘。
所以在重绘时,控件就会依据最新的控件參数来绘制了,所以我们就看到当前控件被缩放了。
(4)、set函数调用频率是多少:因为我们知道动画在进行时,每隔十几毫秒会刷新一次,所以我们的set函数也会每隔十几毫秒会被调用一次。
讲了这么多,就是为了强调一点:ObjectAnimator仅仅负责把当前运动动画的数值传给set函数。至于set函数里面怎么来做。是我们自己的事了。
好了,在知道了ObjectAnimator的原理以后,以下就来看看怎样自己定义一个ObjectAnimator的属性吧。
二、自己定义ObjectAnimator属性
上面我们已经看了使用View自带的set函数所相应属性的方法,并且理解了ObjectAnimator的动画实现原理,以下我们来自己定义一个属性来看看实现效果吧。
我们在開始之前再来捋一下ObjectAnimator的动画设置流程:ObjectAnimator须要指定操作的控件对象,在開始动画时,到控件类中去寻找设置属性所相应的set函数。然后把动画中间值做为參数传给这个set函数并运行它。
所以。我们说了,控件类中必须所要设置属性所要相应的set函数。所以为了自由控制控件的实现,我们这里自己定义一个控件。大家知道在这个自己定义控件中,肯定存在一个set函数与我们自己定义的属性相相应。
我们先来看看这段要实现的效果:
这个效果图与我们上篇自己定义控件实现的效果几乎相同,这个控件中存在一个圆形。也是在动画时先将这个圆形放大,然后再将圆形还原。
1、保存圆形信息类——Point
为了,保存圆形的信息,我们先定义一个类:(Point.java)
public class Point {
private int mRadius; public Point(int radius){
mRadius = radius;
} public int getRadius() {
return mRadius;
} public void setRadius(int radius) {
mRadius = radius;
}
}
这个类非常好理解,仅仅有一个成员变量mRadius,表示圆的半径。
2、自己定义控件——MyPointView
然后我们自己定义一个控件MyPointView,完整代码例如以下:
public class MyPointView extends View {
private Point mPoint = new Point(100); public MyPointView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
protected void onDraw(Canvas canvas) {
if (mPoint != null){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300,300,mPoint.getRadius(),paint);
}
super.onDraw(canvas);
} void setPointRadius(int radius){
mPoint.setRadius(radius);
invalidate();
} }
在这段代码中,首先来看我们前面讲到的set函数:
void setPointRadius(int radius){
mPoint.setRadius(radius);
invalidate();
}
第一点,这个set函数所相应的属性应该是pointRadius或者PointRadius。前面我们已经讲了第一个字母大写和小写无所谓,后面的字母必须保持与set函数全然一致。
第二点,在setPointRadius中,先将当前动画传过来的值保存到mPoint中。做为当前圆形的半径。
然后强制界面刷新
在界面刷新后。就開始运行onDraw()函数:
@Override
protected void onDraw(Canvas canvas) {
if (mPoint != null){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300,300,mPoint.getRadius(),paint);
}
super.onDraw(canvas);
}
在onDraw函数中,就是依据当前mPoint的半径值在(300,300)点外画一个圆;有关画圆的知识。大家能够參考《android Graphics(一):概述及基本几何图形绘制》
3、使用MyPointView
首先,在MyActivity的布局中加入MyPointView的使用(main.xml):
<?xml version="1.0" encoding="utf-8"? >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"> <Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:padding="10dp"
android:text="start anim"
/> <Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="10dp"
android:text="cancel anim"
/>
<TextView
android:id="@+id/tv"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:padding="10dp"
android:background="#ffff00"
android:text="Hello qijian"/> <com.example.BlogObjectAnimator1.MyPointView
android:id="@+id/pointview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tv"/> </RelativeLayout>
布局代码非常好理解。依据效果图中的布局效果来理解。非常easy,就不再多讲
然后看看在MyActivity中,点击start anim后的处理方法:
public class MyActivity extends Activity {
private Button btnStart;
private MyPointView mPointView; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); btnStart = (Button) findViewById(R.id.btn);
mPointView = (MyPointView)findViewById(R.id.pointview); btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doPointViewAnimation();
}
});
}
…………
}
在点击start animbutton后。開始运行doPointViewAnimation()函数,doPointViewAnimation()函数代码例如以下:
private void doPointViewAnimation(){
ObjectAnimator animator = ObjectAnimator.ofInt(mPointView, "pointRadius", 0, 300, 100);
animator.setDuration(2000);
animator.start();
}
在这段代码中。着重看ObjectAnimator的构造方法,首先要操作的控件对象是mPointView,然后相应的属性是pointRadius,然后值是从0到300再到100;
所以在动画開始以后。ObjectAnimator就会实时地把动画中产生的值做为參数传给MyPointView类中的setPointRadius(int radius)函数,然后调用setPointRadius(int radius)。因为我们在setPointRadius(int radius)中实时地设置圆形的半径值然后强制重绘当前界面,所以能够看到圆形的半径会随着动画的进行而改变。
四、注意——何时须要实现相应属性的get函数
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
public static ObjectAnimator ofInt(Object target, String propertyName, int... values)
public static ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)
前面我们已经分别讲过三个函数的使用方法,在上面的三个构造方法中最后一个參数都是可变长參数。我们也讲了,他们的意义就是从哪个值变到哪个值的。
那么问题来了:前面我们都是定义多个值,即至少两个值之间的变化,那假设我们仅仅定义一个值呢,如以下的方式:(相同以MyPointView为例)
ObjectAnimator animator = ObjectAnimator.ofInt(mPointView, "pointRadius",100);
我们在这里仅仅传递了一个变化值100;那它从哪里開始变化呢?我们来看一下效果:
代码例如以下:
ObjectAnimator animator = ObjectAnimator.ofInt(mPointView, "pointRadius",100);
animator.setDuration(2000);
animator.start();
效果图例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
仅且仅当我们仅仅给动画设置一个值时,程序才会调用属性相应的get函数来得到动画初始值。假设动画没有初始值,那么就会使用系统默认值。比方ofInt()中使用的參数类型是int类型的,而系统的Int值的默认值是0,所以动画就会从0运动到100;也就是系统尽管在找到不到属性相应的get函数时,会给出警告,但同一时候会用系统默认值做为动画初始值。
假设通过给自己定义控件MyPointView设置了get函数,那么将会以get函数的返回值做为初始值:
public class MyPointView extends View {
private Point mPoint = new Point(100); public MyPointView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
protected void onDraw(Canvas canvas) {
if (mPoint != null){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300,300,mPoint.getRadius(),paint);
}
super.onDraw(canvas);
} public int getPointRadius(){
return 50;
} public void setPointRadius(int radius){
mPoint.setRadius(radius);
invalidate();
} }
我们在这里加入了getPointRadius函数,返回值是Int.有些同学可能会疑惑:我怎么知道这里要返回int值呢?
我们前面说过当且仅当我们在创建ObjectAnimator时,仅仅给他传递了一个过渡值的时候,系统才会调用属性相应的get函数来得到动画的初始值!所以做为动画的初始值,那么在创建动画时过渡值传的什么类型,这里的get函数就要返回类型
public static ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)
比方上面的ofObject,get函数所返回的类型就是与最后一个參数Object... values,相同类型的。
在我们在MyPointView加入上PointRadius所相应的get函数以后又一次运行动画:
ObjectAnimator animator = ObjectAnimator.ofInt(mPointView, "pointRadius",100);
animator.setDuration(2000);
animator.start();
此时的效果图例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
三、经常使用函数
有关经常使用函数这一节事实上没有太多讲的必要。
因为ObjectAnimator的函数都是从ValueAnimator中继承而来的。所以使用方法和效果与ValueAnimator是全然一样的。我们这里仅仅解说一下Evaluator的使用方法,其他的也就不再讲了。
1、使用ArgbEvaluator
我们搜一下TextView全部的函数发现,TextView有一个set函数能够改变背景色:
public void setBackgroundColor(int color);
大家能够回想到,我们在ValueAnimator中也曾改变过背景色,使用的是ArgbEvaluator。在这里我们再回想下ArgbEvaluator,它的实现代码例如以下:
public class ArgbEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24);
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff; int endInt = (Integer) endValue;
int endA = (endInt >> 24);
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff; return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}
有关它具体实现的原理。前面篇章中我们已经讲过了,这里主要说一点。ArgbEvaluator的返回值是Integer类型,所以我们要使用ArgbEvaluator的话,构造ObjectAnimator时必须使用ofInt()
以下我们来看看使用ArgbEvaluator的代码:
ObjectAnimator animator = ObjectAnimator.ofInt(tv, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
animator.setDuration(8000);
animator.setEvaluator(new ArgbEvaluator());
animator.start();
然后我们来看下代码效果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
2、其他函数
以下把其他所涉及到的函数的列表列在以下。大家能够參考ValueAnimator的使用方法来使用。有关自己定义插值器和Evaluator的部分,能够參考《Animation动画具体解释(五)——高级进阶(一)》
(1)、经常使用函数
/**
* 设置动画时长,单位是毫秒
*/
ValueAnimator setDuration(long duration)
/**
* 获取ValueAnimator在运动时。当前运动点的值
*/
Object getAnimatedValue();
/**
* 開始动画
*/
void start()
/**
* 设置循环次数,设置为INFINITE表示无限循环
*/
void setRepeatCount(int value)
/**
* 设置循环模式
* value取值有RESTART,REVERSE,
*/
void setRepeatMode(int value)
/**
* 取消动画
*/
void cancel()
(2)、监听器相关
/**
* 监听器一:监听动画变化时的实时值
*/
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
//加入方法为:public void addUpdateListener(AnimatorUpdateListener listener)
/**
* 监听器二:监听动画变化时四个状态
*/
public static interface AnimatorListener {
void onAnimationStart(Animator animation);
void onAnimationEnd(Animator animation);
void onAnimationCancel(Animator animation);
void onAnimationRepeat(Animator animation);
}
//加入方法为:public void addListener(AnimatorListener listener)
(3)、插值器与Evaluator
/**
* 设置插值器
*/
public void setInterpolator(TimeInterpolator value)
/**
* 设置Evaluator
*/
public void setEvaluator(TypeEvaluator value)
到这里,有关ObjectAnimator的知识就讲完了,下篇再讲讲联合动画和xml中实现动画的方法。
假设本文有帮到你,记得加关注哦
源代码下载地址:
csdn:http://download.csdn.net/detail/harvic880925/9445785
github:https://github.com/harvic/BlogResForGitHub
请大家尊重原创者版权,转载请标明出处,谢谢
自己定义控件三部曲之动画篇(七)——ObjectAnimator基本使用的更多相关文章
- 自己定义控件三部曲之动画篇(十三)——实现ListView Item进入动画
前言:宝剑锋从磨砺出,梅花香自苦寒来 相关文章: <Android自己定义控件三部曲文章索引>: http://blog.csdn.net/harvic880925/article/det ...
- 自己定义控件三部曲视图篇(二)——FlowLayout自适应容器实现
前言:我最大的梦想,就是有一天.等老了坐在摇椅上回望一生,有故事给孩子们讲--. 相关文章: <Android自己定义控件三部曲文章索引>:http://blog.csdn.net/har ...
- android--------自定义控件 之 基本流程篇
在我们平常的Android开发中经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件 自定义控件可以设计出很多你想要的功能和模块,在开发中是很重要的 ...
- android--------自定义控件 之 基本实现篇
前面简单的讲述了Android中自定义控件中的几个方法,今天通过代码来实现一个简单的案例 自定义一个扇形图 自定义控件示例: 这里先介绍继承View的方式为例 public class Circula ...
- 自己定义控件 播放GIF动画
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- Android自己定义控件之应用程序首页轮播图
如今基本上大多数的Android应用程序的首页都有轮播图.就是像下图这种(此图为转载的一篇博文中的图.拿来直接用了): 像这种组件我相信大多数的应用程序都会使用到,本文就是自己定义一个这种组件,能够动 ...
- Android自己定义控件:进度条的四种实现方式
前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ...
- 转:自定义控件三部曲之动画篇——alpha、scale、translate、rotate、set的xml属性及用法
第一篇: 一.概述 Android的animation由四种类型组成:alpha.scale.translate.rotate,对应android官方文档地址:<Animation Resour ...
- 自己定义控件事实上非常easy1/6
尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 上一节我们粗略地讲了下怎样去实现我 ...
随机推荐
- yii的criteria的用法
Yii的Active Recorder包装了很多. 特别是把SQL中 把where,order,limit,IN/not IN,like等常用短句都包含进CDbCriteria这个类中去,这样整个代码 ...
- 运行Django项目指定IP和端口
默认IP和端口 python manage.py runserver 指定端口: python manage.py runserver 192.168.12.12:8080 此时会报错,我们需要修改配 ...
- A - Design Tutorial: Learn from Math(哥德巴赫猜想)
Problem description One way to create a task is to learn from math. You can generate some random mat ...
- sql学习--update
两种修改形式 第一种:静态插入 ,notes='began career selling ...balabala' where jc='johnny ca' 第二种: --注意别名和on后边的表连接不 ...
- node函数buf.readDoubleBE详解
offset {Number} 0 noAssert {Boolean} 默认:false 返回:{Number} 从该 Buffer 指定的带有特定尾数格式(readDoubleBE() 返回一个较 ...
- Css小动画
html页面: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF ...
- Linux while和for循环简单分析
一.循环重定向 最近遇到了一种新的循环重定向写法,由于没看懂,说以网上搜索了一下,然后再此分享一下: while read line do ...... done < file 刚开始看,不明 ...
- Centos6.6 安装Subversion服务
一.介绍 Subversion 简称就是svn服务器,用来托管代码的,类似的还有git 1)Centos6.6 2)Subversion 二.安装 yum -y install subversion ...
- Model2
Model1: Model2:
- 偏函数应用(Partial Application)和函数柯里化(Currying)
偏函数应用指的是固化函数的一个或一些参数,从而产生一个新的函数.比如我们有一个记录日志的函数: 1: def log(level, message): 2: print level + ": ...