View的滑动实现之三(使用动画,属相动画及延时策略)

来源:互联网 发布:javascript 线程 编辑:程序博客网 时间:2024/04/30 01:39

前面我们已经介绍了两种View的滑动实现,今天我们介绍另一种滑动方式,即使用动画。通过动画我们能够让一个View进行平移,而平移就是一种动画。使用动画来移动View主要操作的是translateX和translateY属性,既可以使用传统的View动画,也可以采用属性动画。但是,如果使用属性动画的话,为了兼容android3.0以下的版本,需要使用开源动画库nineoldandroids,大家感兴趣的可以自行查看。



好了,首先说一下View动画,本示例实现了在100ms内讲一个View从原始位置向右下角移动100个像素。代码如下:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:fillAfter="true"    android:zAdjustment="normal"    >    <translate        android:duration="100"        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="100"        android:toYDelta="100"        android:interpolator="@android:anim/linear_interpolator"        /></set>
上面代码中的android:fillAfter标识是否使动画后的状态保留。android:zAdjustment允许在动画播放期间,调整播放内容在Z轴方向的顺序,normal:正在播放的动画内容保持当前的Z轴顺序;top:在动画播放期间,强制把当前播放的内容放到其他内容的上面;bottom:在动画播放期间,强制把当前播放的内容放到其他内容之下。

还需要加以说明的是android:interpolator属性,它表示动画系和或是动画所采用的插值器,插值器影响动画速度。这个属性可以不指定,默认为@android:anim/accelerate_decelerate_interpolator,即加减速插值器。后面会给大家进行详细的讲解。


现在再介绍一下如何使用属性动画实现平移动画,使用属性动画就更简单了,代码如下:

ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(100).start();



上面的两种动画都可以实现移动View的操作,但是View动画是对View的影像做操作,它并不能改变View的位置参数,包括宽高,并且如果想要保留动画结束后的状态,还需要把fillAfter设置为true,否则动画完成后其动画效果就会消失。这说的是什么意思呢,举个例子,如果有一个button,你通过View动画把它向右移动了100px,可是你会发现在移动后的位置的button并不能够响应点击事件即onClick事件,原始的位置还是可以响应点击事件的。这是为什么呢,其实上面已经给出了答案,View动画不会改变View的位置信息,只是对影像进行操作,所以button的真身还在原始的位置并没有改变。

从android3.0开始,属相动画可以解决上面的问题,为什么说从android3.0开始呢,虽说属相动画是从android3.0才有的,那么大家就会问,前面不是说了吗,在android3.0以前可以使用nineoldandroids来实现属相动画啊,确是如此,但是还要告诉大家的是,在android3.0以下的通过nineoldandroids来实现的属相动画本质上仍然是View动画,相信现在大家应该知道为什么要说android3.0以后了吧。

那么,难道,在android3.0之前使用View动画不能够实现属相动画那样的把View的“真身”也给移动吗,当然可以,在这里给大家一个简单的解决办法,我们可以在新位置预先创建一个和目标button一样的button,他们不但外观一样连onClick()事件也一样。当目标button完成平移动画后,就把目标button隐藏,同时把预先创建的button显示出来,通过过这样的方法,就可以屏蔽原始位置的点击事件并且使动画后的button可以响应onClick事件了。

好了,动画实现View的滑动就说到这里,我们再来说一下,如何通过动画实现View的弹性滑动。

其实动画本来就是一种渐进的过程,上面介绍的动画过程天生就是具有弹性的。我们还可以使用动画来实现一些动画不能够实现的效果,现在,我们使用动画来模仿前面提到的Scroller实现View弹性滑动的过程,代码如下:

final int startX = 0;final int deltaX = 100;ValueAnimator animator = ValueAnimator.ofInt(0, 1).setDuration(1000);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        float fraction = animation.getAnimatedFraction();        targetView.scrollTo(startX + (int) (deltaX * fraction), 0);    }});animator.start();

 
在上述代码中,我们的动画本质上没有作用于任何对象上,他只是在1000ms内完成了整个动画过程,而我们只是利用了Value Animator中的”插值器“,然后使用scroll To来实现View的移动,代码中的add Update Listener会在动画的每一帧的时候都会被调用,通过它获得一个百分比配合scrollTo方法来实现View的滑动。


还有一种实现弹性滑动的方法,就是延时策略,它的核心思想是通过发送一系列延时消息从而达到一种渐近式的效果,具体来说可以使用Handler或是View的PostDelayed方法,或是线程的sleep方法。对于PostDelayed方法来说,我们可以通过它来延时发送一个消息,然后再消息中进行View的滑动,如果接连不断的发送这种延时消息,那么就可以实现弹性滑动的效果。对于sleep方法来说,通过在while循环中不断的滑动View和sleep,就可以实现弹性滑动的效果。


下面给大家介绍一种,Handler的示例,其他的方法大家可以自己去尝试。


代码:

private static final int MESSAGE_SCROLLTO = 1;private static final int FRAME_COUNT = 30;private static final int DELAYED_TIME = 33;private int count = 0;private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        switch (msg.what) {            case MESSAGE_SCROLLTO: {                count++;                if(count<=FRAME_COUNT){                    float fraction=count/(float)FRAME_COUNT;                    int scrollX=(int)(fraction*100);                    mButton.scrollTo(scrollX,0);                    mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLLTO,DELAYED_TIME);                }                break;            }            default:                break;        }    }};
好了,我们到现在已经介绍完了所有的View的滑动的方法,现在我们来对比一下:

先来看一下改变布局的方式,它除了使用比较麻烦以外,没有明显的缺点,它的主要使用对象是一些具有交互性的View,因为这些View需要与用户交互,如果直接通过动画去实现一定会存在问题。

再来看一下scrollTo/scrollBy方法,它是View提供的原声方法,其作用是专门用于View的滑动,他可以比较方便的实现滑动效果而不影响内部元素的点击事件,但是他的缺点也很明显,它只能滑动View的内容不能滑动View本身。

最后看一下动画,在Android3.0以上使用属性动画没有明显的缺点,如果使用的是View动画或是在Android3.0以前使用属性动画,均不能改变View本身的属性,在实际的使用中,如果不需要响应用户的交互,那么使用动画来实现滑动比较合适,否则就不太合适了,但是动画还有一个明显的优势,就是一些复杂的效果必须通过动画才能后实现。



好了,View的滑动和弹性滑动的介绍就告一段落了,后面会给大家详细介绍一下动画机制 。


0 0
原创粉丝点击