简介
NineOldAndroids是GitHub上的一个开源项目,其作用是为了在低版本android上(API11以下)使用属性动画。它的原理其实也很简单,主要就是判断当前sdk版本,如果大于API11,那么就调用官方的API,否则自己实现动画效果。另外,在API使用方面,它与官方的属性动画基本一致。比如ObjectAnimator、ValueAnimator等等。 GitHub网址:https://github.com/JakeWharton/NineOldAndroids 跟官方类似,NineOldAndroids主要是通过ObjectAnimator、ValueAnimator、AnimatorSet完成属性动画。
环境搭建
第一步:从官方下载源码包,然后将其中的library导入到AndroidStudio工程中。
第二步:新建一个Module,在其中放置多个onClick属性值依次伙fun1、fun2….的Button控件,再放置一个id值为ImageView的ImageView控件。
第三步:在MainActivity中定义一个private类型的ImageView类型的变量imageView,然后在onCreate()方法中通过如下代码为该变量赋值:
imageView = (ImageView) findViewById(R.id.imageView);
示例1:水平右移200单位
public void fun1(View view) {//水平右移200单位
ObjectAnimator.ofFloat(imageView, "translationX", 200)
.setDuration(2000)
.start();
}
NineOldAndroids提供了一个名为ViewHelper的类来兼容以前的API,因为像setAlpha()、setTranslationX()等方法在低版本中是没有的,所以NineOldAndroids提供了ViewHelper类,使得我们不必关心API版本。 ViewHelper提供了一系列静态set/get方法去操作View的各种属性,比如透明度、偏移量、旋转角度等等,这大大方便了我们的使用,并且有个好处就是不用考虑低版本的兼容性问题。
示例2:竖直向下移200单位
public void fun2(View view) {//竖直向下移200单位
ValueAnimator animator = ValueAnimator.ofFloat(1, 200)
.setDuration(2000);
animator.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float curVal = (float) animation.getAnimatedValue();
ViewHelper.setTranslationY(imageView,curVal);
}
});
}
示例3:水平移动200,竖直移动200,并且透明度发生改变
public void fun3(View view) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(imageView,"translationX",200),
ObjectAnimator.ofFloat(imageView,"translationY",200),
ObjectAnimator.ofInt(imageView,"alpha",1,0)
);
set.setDuration(2000);
set.start();
}
当然,这个效果也可以通过PropertyValuesHolder来实现:
ObjectAnimator.ofPropertyValuesHolder(imageView,
PropertyValuesHolder.ofFloat("translationX", 100),
PropertyValuesHolder.ofFloat("translationY", 100),
PropertyValuesHolder.ofInt("alpha", 1, 0)
).setDuration(2000).start();
Google官方提供了ViewPropertyAnimator类简化了View动画,只要我们调用View提供的animate方法即可返回ViewPropertyAnimator实例,然后我们可以调用其x、translationX、alpha、rotation等方法很方便的实现动画。NineOldAndroids库也提供了用来实现类似功能的ViewPropertyAnimator类,但是使用方式上有点不一样。它是通过ViewPropertyAnimator提供静态工厂方法animate,并且在参数中必须绑定一个view,然后返回ViewPropertyAnimator实例。
示例4:利用ViewPropertyAnimator实现水平移动200,竖直移动200,并且透明度改变到原来一半的效果。
public void fun5(View view) {
ViewPropertyAnimator.animate(imageView)
.translationX(200)
.translationY(200)
.alpha(0.5f) //透明度逐渐过度到原来的一半
.setDuration(2000)
.start();
}
ViewPropertyAnimator在性能上要比使用ObjectAnimator来实现多个同时进行的动画要高的多:举个例子,假如要对View使用移动和透明度的动画,使用ViewPropertyAnimator的话,某个时间点上我们只需要调用一次invalidate()方法刷新界面就行了,而使用ObjectAnimator的话,移动的动画需要调用invalidate(),透明度的动画也需要调用invalidate()方法,在性能上使用AnimationSet比ViewPropertyAnimator要低,但是有的时候我们还是需要使用ObjectAnimator,比如,在某个时间内,我们需要将View先变大在变小在变大等复杂情况,这时候ObjectAnimator就派上用场了。示例代码:
ObjectAnimator.ofInt(mDownView, "scaleX", 0 ,100 ,0, 100)
.setDuration(100)
.start()
示例:实现绚丽的ListView左右滑动删除的Item效果
要求: 当滑动Item超过一半的时候,Item的透明度就变成0时,抬起手指的item就会被删除;当Item的透明度不为0的时候,抬起手指Item会回到起始位置;滑动删除了Item的时候,ListView的其他item会出现向上或者向下滚动的效果
思路:
- 根据手指触摸的点来获取点击的是ListView的哪一个Item
- 当手指在屏幕上面滑动的时候,使Item跟随手指的滑动而滑动
- 当抬起手指的时候,根据滑动的距离或者手指在屏幕上面的速度来判断Item是滑出屏幕还是滑动至原来位置
- Item滑出屏幕时,使ListView的其他item产生向上挤压或者向下挤压的效果