安卓系统的默认属性
安卓系统中提供了一系列的属性动画供你使用,常用的包括:
| 属性名称 | 描述 |
|---|---|
| X | 在父容器(非屏幕)的距离左侧的距离,即X轴的距离 |
| Y | 在父容器(非屏幕)的距离顶部的距离,即Y轴的距离 |
| scaleX | X轴方向的缩放,Y轴大小不变,从中间向两侧或者从两侧向中间 |
| scaleY | Y轴方向的缩放,X轴的大小不变,从中间向两侧或者从两侧向中间 |
| alpha | 透明度,为0时全透明,1时不透明 |
但是系统提供的属性具有一定的局限性,它只能按照系统设置好的轨迹运动,比如要改变一个图像的大小的时候,默认的是这个样子的:
1.X轴方向缩放

2.Y轴方向缩放

可以看到,在缩放的时候是一种从中间向两边扩展的趋势,此时比如我想要一种类似于幕布下拉的趋势出现,它就不能完成我的要求了。
了解自定义属性
上一篇文章中简单介绍了animator的一些基本使用,这次介绍一下除了可以使用系统提供的默认属性,还可以自定义属性,在代码中使用。
ObjectAnimator的第一个参数允许我们传一个Object进去,而不是具体的某个view或者viewgroup,这样的做的目的是提高属性动画的适配范围,我们可以把自己自己定义一个类,用来包裹你的view,然后通过设置这个类的一些getter和setter方法来产生你想要的动画效果。
这个包裹类必须要有setter方法,因为Animator这个时间引擎正式通过计算值来设置view的属性而打到动画不断更新的目的。而getter方法可以不设置,但是假如传的value值只有一个,会默认把参数作为结束值,此时你必须设置setter方法,动画系统会把setter中的值设为起始值。
通过一个简单的例子拉使用一下:
现在我有一个图片,我需要以幕布下拉的方式来展现一张图片,思路是这样的,假设从Y轴向下展示,此时我要做一个包装类出来,传入要动画的view作为参数,通过设置view的宽度来不断更新view。
public class ImageViewWrapper {
private ImageView imageView;
private ViewGroup.LayoutParams lp;
public ImageViewWrapper(ImageView imageView) {
this.imageView = imageView;
imageView.setScaleType(ImageView.ScaleType.CENTER);
lp = imageView.getLayoutParams();
}
public ImageView getImageView() {
return imageView;
}
public void setImageView(ImageView imageView) {
this.imageView = imageView;
}
}以上方法设定了一个imageview包裹器,并获取了layoutparams,这个lp是用来设置新的布局参数的,然后我们把layoutparams的scaletype设置为了center,这样图片的大小就会始终是原始大小,不会因为width或者height中的某一个值改变而按比例缩放。
下面定义我们自己的属性设置于属性获取器:
public void setHeight(float height) {
lp.height = (int) height;
imageView.setLayoutParams(lp);
}设置imageview 的高度,要通过layoutparams来设置。这样我们就可以在ObjectAnimator中使用我们自定义的属性了。
此处使用的是ofFloat(Object target, String propertyName, float... values)
ImageViewWrapper i = new ImageViewWrapper(imageView);
ObjectAnimator animator1 = ObjectAnimator.ofFloat(i, "height", 0, 100);
animator1.setDuration(1000);
animator1.start()效果如下:

同样的方式适用于width改变,效果如下:

Note: propertyname这个值(也就是ObjectAnimator.ofFLoat()中的第二个参数)一定要与setter中的一样。
API中还可以使用Property来获取属性名称,ofFloat(T target, Property<T, Float> property, float... values)
不过这个方式是利用了反射射,此处不推荐:
Property p = Property.of(ImageViewWrapper.class, Float.class, "width");
ObjectAnimator animator = ObjectAnimator.ofFloat(i, p, 0, 100);效果与上边一样的。
此处有一个方法要介绍一下
ofInt (Object target,
String xPropertyName,
String yPropertyName,
Path path)在这个方法中可以传入路径作为参数,让物体按我们自己想要的路径来运动。
Path path=new Path();
path.addCircle(200,200,100, Path.Direction.CW);
ObjectAnimator animator4=ObjectAnimator.ofFloat(imageView,"X","Y",path);
animator.setDuration(5000);这里设置一个简单的圆形路径,然后调用animator4.start()
方法,图片就会随着我们指定的路径一路运动下去,有了这个功能,属性动画更加强大了。

最后附上github地址
Demo