1 Android属性动画中ofXX函数概述
前面一篇属性动画文章中讲解了如何利用ObjectAnimator实现几种补间动画效果和如何自定义ObjectAnimator属性,其中用到了ObjectAnimator对象的ofInt,ofFLoat,ofObject,但这些函数都有众多的重载函数,这一篇接着讲解ObjectAnimator众多的ofXXX函数的用法。
观看本篇文章请务必先看Android动画之ValueAnimator用法和自定义估值器
ObjectAnimator of函数列表:
ofArgb(Object target, String propertyName, int... values) api21可用
ofArgb(T target, Property<T, Integer> property, int... values) api21可用
ofFloat(Object target, String propertyName, float... values) api11 可用
ofFloat(Object target, String xPropertyName, String yPropertyName, Path path) api21可用
ofFloat(T target, Property<T, Float> property, float... values) api14可用
ofFloat(T target, Property<T, Float> xProperty, Property<T, Float> yProperty, Path path) api21可用
ofInt(Object target, String propertyName, int... values) api11可用
ofInt(Object target, String xPropertyName, String yPropertyName,Path path) api21可用
ofInt(T target, Property<T, Integer> property, int... values) api14可用
ofInt(T target, Property<T, Integer> xProperty,Property<T, Integer> yProperty, Path path) api21可用
ofMultiFloat(Object target, String propertyName,float[][] values) api21可用
ofMultiFloat(Object target, String propertyName, Path path) api21可用
ofMultiFloat(Object target, String propertyName,
TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) api21可用
ofMultiInt(Object target, String propertyName, int[][] values) api21可用
ofMultiInt(Object target, String propertyName, Path path) api21可用
ofMultiInt(Object target, String propertyName,
TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) api21可用
ofObject(Object target, String propertyName,
@Nullable TypeConverter<PointF, ?> converter, Path path) api21可用
ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values) api11
ofObject(T target, Property<T, P> property,
TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) api21
ofObject(T target, @NonNull Property<T, V> property,
@Nullable TypeConverter<PointF, V> converter, Path path) api2可用
ofObject(T target, Property<T, V> property, TypeEvaluator<V> evaluator, V... values) api14可用
ofPropertyValuesHolder(Object target, PropertyValuesHolder... values) api11可用
2 OfFloat & ofInt
把ofFLoat和ofInt两个函数一起讲解是因为这两个函数除了类型不一样,重载函数很相似。
ofFloat(Object target, String propertyName, float... values)
ofFloat(Object target, String xPropertyName, String yPropertyName, Path path)
ofFloat(T target, Property<T, Float> property, float... values)
ofFloat(T target, Property<T, Float> xProperty, Property<T, Float> yProperty, Path path)
ofInt(Object target, String propertyName, int... values)
ofInt(Object target, String xPropertyName, String yPropertyName,Path path)
ofInt(T target, Property<T, Integer> property, int... values)
ofInt(T target, Property<T, Integer> xProperty,Property<T, Integer> yProperty, Path path)
ObjectAnimator 的ofFloat和ofInt函数用法相似,所以只讲解ofFloat,
ofFloat(Object target, String propertyName, float... values)
这个函数比较简单,第一个参数传入目标对象,第二个参数传入要改变的属性(配合setXX函数,关于如何定义propertyName前面的文章中已经说明),第三个参数是个渐变属性,可以传多个值。
代码示例:
实现TextView的旋转:
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mTextView, "rotation", 0, 270);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofFloat(Object target, String xPropertyName, String yPropertyName, Path path)
可以同时操纵两个参数变化,实现动画。
参数说明:
target:动画目标对象,这个目标对象有些特别,沿着一条路径Path能够使用两个属性,路径Path动画在二维空间中移动,由动画坐标(x,y)决定效果,(重要)所以对象必须有两个函数一个是setNameX(),另外一个是setNameY(),类似view的setTranslationX,SetTranslationY,当然也可以自己定义属性,同时对应的xPropertyName和yPropertyName分别为translationX和translationY。
xPropertyName:Path对应的X轴方向的属性值,
yPropertyName:Path对应的Y轴方向的属性值,
path:动画路径。
代码示例:
TextView 在X轴和Y轴方向上移动
Path path = new Path();
path.moveTo(0,0);
path.lineTo(50,50);
path.lineTo(100,20);
path.lineTo(900,400);
path.lineTo(500,1000);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mTextView, "translationX","translationY",path );
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
上面的示例代码利用了translationX和translationX属性,这两个属性是View的自带的属性,同时也可以是两个互不相干的属性,可以实现类似组合动画的效果。
Path path = new Path();
path.moveTo(0,0);
path.lineTo(50,1);
path.lineTo(100,2);
path.lineTo(900,0.5f);
path.lineTo(500,1);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mTextView, "translationX","scaleX",path );
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofFloat(T target, Property<T, Float> property, float... values)
参数说明:
target:动画目标对象
property:动画作用的属性,有了这个属性对象, 就可以不用写属性对应的字段值,类似不用写“scale”
values:动画取值,如果是一个值则将target开始的状态作为开始值,将values的一个值,作为结束值,如果是两个值则第一个为动画开始值,第二个为动画结束值。
这个函数用到了Property属性,是API14添加的方法,不知道大家注意到没有,每次使用属性动画,我们都需要记得目标对象的setXXX函数后面的相应字符串,虽然不复杂但有时确实会记不清,需要再次确认,而这个带有Property的函数就大大简化了这个过程。
Android为我们提供了简单的常量对象来实现旋转动画:
ObjectAnimator.ofFloat(mTextView, View.ROTATION, 0,30);
这里的View.ROTATION就是个Property对象,可以简单地实现旋转的属性动画。
View.ROTATION源码
public static final Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
@Override
public void setValue(View object, float value) {
object.setRotation(value);
}
@Override
public Float get(View object) {
return object.getRotation();
}
};
View.ROTATION示例
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mTextView, View.ROTATION, 0,270);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
View中具有和View.ROTATION作用的常量还有如下:
ALPHA,TRANSLATION_X,TRANSLATION_Y,TRANSLATION_Z,X,Y,ROTATION, ROTATION_X , ROTATION_Y,SCALE_X,SCALE_Y。
自定义Property
分析上面常量的他们都是实现了FloatProperty,或者IntProperty然后重写setValue和get方法,而FloatProperty,IntProperty又是继承了Property,所以我们可以通过实现FloatPropety,IntProperty或者直接实现Property来自定义Property。
自定义Property:
public static class MyProperty extends Property<TextView,String>{
public MyProperty(String name) {
super(String.class, name);
}
@Override
public String get(TextView object) {
return object.getText().toString();
}
@Override
public void set(TextView object, String value) {
object.setText(value);
}
}
自定义估值器:
public static class IntEvaluator implements TypeEvaluator<String>{
@Override
public String evaluate(float fraction, String startValue, String endValue) {
int startInt = Integer.parseInt(startValue) ;
int endInt = Integer.parseInt(endValue);
int cur = (int) (startInt + fraction * (endInt - startInt));
return cur+"";
}
}
使用自定义Property:
IntEvaluator intEvaluator = new IntEvaluator();
MyProperty property = new MyProperty("text");
ObjectAnimator objectAnimator = ObjectAnimator.ofObject(mTextView,property,intEvaluator,"1", "10");
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofFloat(T target, Property<T, Float> xProperty, Property<T, Float> yProperty, Path path)
函数也用到了Property属性,需要结合property和Path,类似上面函数的用法,不再说明。
3 ofArgb 颜色属性动画
ofArgb(Object target, String propertyName, int... values) 对颜色属性进行动画。
参数说明:
target:动画作用对象
propertyName:动画作用的属性
values:动画使用的可变参数
代码示例:
ObjectAnimator objectAnimator = ObjectAnimator.ofArgb(mTextView,"backgroundColor", Color.RED, Color.GREEN);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofArgb(T target, Property<T, Integer> property, int... values)
用到了Property属性,但是View中没有类似ROTATION属性的对颜色属性的简写,可以自定义Property,下面的例子只是数值的渐变,如果真的需要颜色渐变,需要设置颜色估值器:
public static class MyProperty extends Property<TextView,Integer>{
public MyProperty(String name) {
super(Integer.class, name);
}
@Override
public Integer get(TextView object) {
Drawable drawable = object.getBackground();
if (drawable instanceof ColorDrawable){
return ((ColorDrawable) drawable).getColor();
}
return Color.YELLOW;
}
@Override
public void set(TextView object, Integer value) {
object.setBackgroundColor(value);
}
}
使用:
MyProperty property = new MyProperty("background");
ObjectAnimator objectAnimator = ObjectAnimator.ofArgb(mTextView,property, Color.RED, Color.GREEN);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
4 ofMultiFloat,ofMultiInt
被称为多参数布局,用的不太多,下面简单介绍:
ofMultiFloat(Object target, String propertyName,float[][] values)
ofMultiFloat(Object target, String propertyName, Path path)
ofMultiFloat(Object target, String propertyName,
TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values)
ofMultiInt(Object target, String propertyName, int[][] values)
ofMultiInt(Object target, String propertyName, Path path)
ofMultiInt(Object target, String propertyName,
TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values)
ofMultiFloat和ofMultiInt用法相似,由于上面只介绍了ofFloat,下面只介绍ofMultiInt方法:
ofMultiInt(Object target, String propertyName, int[][] values)
参数说明:
propertyName:进行动画的属性名
values[][]:二维数组,至少两组数据,每个values[]中存放一个setter函数中所有的参数,然后从values[0]中取值为动画开始值,从values[最后一组]中取值为动画最后的值,如果之间还有值,就作为过渡,从values[0]-values[1]-........(大家明白的)
需要自定义view添加getter,setter函数。
代码示例:
public class ViewDemo24 extends android.support.v7.widget.AppCompatTextView {
public ViewDemo24(Context context) {
this(context,null,0);
}
public ViewDemo24(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public ViewDemo24(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
}
public void setMulText(int data1,int data2){
String data = "";
data = data + data1 + data2;
setText(data);
}
public String getMulText(){
return getText().toString();
}
}
使用:
int[][] data = {{1,9},{4,12}} ;
ObjectAnimator objectAnimator = ObjectAnimator.ofMultiInt(viewDemo24,"mulText",data);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofMultiInt(Object target, String propertyName, Path path)
用法和上面的函数类似,只不过把二维数组换成了Path,并且setter函数只能接收两个int参数,从path中取动画开始值和结束值(从path.moveTo中取动画开始值,后面的值为动画结束值)。
代码示例
**自定义view还用上面的ViewDemo24 **
Path path = new Path();
path.moveTo(0,6);
path.lineTo(5,9);
ObjectAnimator objectAnimator = ObjectAnimator.ofMultiInt(viewDemo24,"mulText",path);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
ofMultiInt(Object target, String propertyName,TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values)
Converter:把int[]数组转换成需要的T类型,然后利用估值器计算T 得到ObjectAnimator需要的类型。
依然用上面的自定义view ,setter函数需要两个参数:
用到的自定义T类型:
public static class Point {
int x;
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
自定义类型转换,把上面自定义的Point类型转换成int[]数组:
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static class IntConverter extends TypeConverter <Point ,int[]>{
public IntConverter(Class<Point> fromClass, Class<int[]> toClass) {
super(fromClass, toClass);
}
@Override
public int[] convert(Point value) {
int[] intarr = {value.getX(),value.getY()};
return intarr;
}
}
自定义估值器:
public static class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int startxInt = startValue.getX() ;
int endxInt = endValue.getX();
int curx = (int) (startxInt + fraction * (endxInt - startxInt));
int startyInt = startValue.getY() ;
int endyInt = endValue.getY();
int cury = (int) (startyInt + fraction * (endyInt - startyInt));
Point point = new Point();
point.setX(curx);
point.setY(cury);
return point;
}
}
代码中使用:
IntConverter intConverter = new IntConverter(Point.class,int[].class);
PointEvaluator pointEvaluator = new PointEvaluator();
Point point1 = new Point();
point1.setX(1);
point1.setY(5);
Point point2 = new Point();
point2.setX(4);
point2.setY(9);
ObjectAnimator objectAnimator = ObjectAnimator.ofMultiInt(viewDemo24,"mulText",intConverter,pointEvaluator,point1,point2);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
5 ofObject
对对象进行动画:
ofObject(Object target, String propertyName,
@Nullable TypeConverter<PointF, ?> converter, Path path)
ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)
ofObject(T target, Property<T, P> property,
TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values)
ofObject(T target, @NonNull Property<T, V> property,
@Nullable TypeConverter<PointF, V> converter, Path path)
ofObject(T target, Property<T, V> property, TypeEvaluator<V> evaluator, V... values)
上面讲解了ofInt ,ofFloat,ofMultiInt,ofMultiFloat等函数,仔细观察上面的ofObject函数,可以分析得到ofObject把类型泛型化了,每个函数都提供了TypeEvaluator供ObjectAnimator识别参数,所以ofObject的用法和ofInt,ofFloat相同。
ofObject(T target, Property<T, V> property, TypeEvaluator<V> evaluator, V... values)
参数说明:
target:动画目标对象
property:自定义property,内部调用getter,setter函数,不用再指定propertyName
evaluator:估值器,生成动画所需对象
values:动画传入参数
利用ofObject 实现view的移动
自定义类:
public static class Point {
int x;
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
自定义property
public static class MyProperty2 extends Property<TextView,Point>{
public MyProperty2(String name) {
super(Point.class, name);
}
@Override
public Point get(TextView object) {
Point point = new Point();
point.setX((int) object.getTranslationX());
point.setY((int) object.getTranslationY());
return point;
}
@Override
public void set(TextView object, Point value) {
object.setTranslationX(value.getX());
object.setTranslationY(value.getY());
}
}
自定义Evaluator估值器
public static class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int startxInt = startValue.getX() ;
int endxInt = endValue.getX();
int curx = (int) (startxInt + fraction * (endxInt - startxInt));
int startyInt = startValue.getY() ;
int endyInt = endValue.getY();
int cury = (int) (startyInt + fraction * (endyInt - startyInt));
Point point = new Point();
point.setX(curx);
point.setY(cury);
return point;
}
}
使用:
MyProperty2 property2 = new MyProperty2("tran");//參數只是为了标识无具体意义
PointEvaluator evaluator = new PointEvaluator();
Point point1 = new Point();
point1.setY(0);
point1.setX(100);
Point point2 = new Point();
point2.setY(700);
point2.setX(1000);
ObjectAnimator objectAnimator = ObjectAnimator.ofObject(mTextView,property2,evaluator,point1,point2);
objectAnimator.setDuration(3000);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.setRepeatCount(-1);
objectAnimator.start();
6 ofPropertyValuesHolder(Object target, PropertyValuesHolder... values)
参数说明:
target:动画目标对象
values:PropertyValuesHolder 动画可变参数。
多动画执行,多个动画一起执行。
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 1,2);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY",0, 1);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("alpha", 0.5f,1.0f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mTextView, holder1, holder2, holder3);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(-1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
Keyframe 实现关键帧操作(来自Android Developer)
利用Keyframe可以添加一些关键帧,来控制动画的执行,例如:
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);
上面的代码作用为动画执行到一半时旋转360度,动画执行完时再从360旋转到0度。关键帧的作用和插值器的作用一样都是动画执行过程中,返回动画完成程度。
自定义插值器
ofXXX函数全部讲完了
Animation动画概述和执行原理
Android动画之补间动画TweenAnimation
Android动画之逐帧动画FrameAnimation
Android动画之插值器简介和系统默认插值器
Android动画之插值器Interpolator自定义
Android动画之视图动画的缺点和属性动画的引入
Android动画之ValueAnimator用法和自定义估值器
Android动画之ObjectAnimator实现补间动画和ObjectAnimator自定义属性
Android动画之ObjectAnimator中ofXX函数全解析-自定义Property,TypeConverter,TypeEvaluator
Android动画之AnimatorSet联合动画用法
Android动画之LayoutTransition布局动画
Android动画之共享元素动画
Android动画之ViewPropertyAnimator(专用于view的属性动画)
Android动画之Activity切换动画overridePendingTransition实现和Theme Xml方式实现
Android动画之ActivityOptionsCompat概述
Android动画之场景变换Transition动画的使用
Android动画之Transition和TransitionManager使用
Android动画之圆形揭露动画Circular Reveal
Android 动画之 LayoutAnimation 动画
Android动画之视图动画的缺点和属性动画的引入