上次讲述了Scroller,今天继续整理View的另外两种弹性滑动方式,并对三种方式加以总结对比异同点。
一.利用动画特性实现类似于Scroller的弹性滑动效果
1.如何用动画实现滑动?
使用动画来实现滑动实质上是让一个View进行平移,而平移就是一种滑动,其主要操作的是View的translationX和translationY这两个属性,动画有两种方式。
(1)View动画
例如下面代码实现:在100ms内将一个View从原位置向右下角移动100个像素(图片系《Android开发艺术探索》书中的代码)
(2)属性动画
为了兼容3.0以下版本,需要采用开源动画库。例如,下面代码实现:将View在100ms内向右平移100像素。
ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(100).start();
事实上,因为动画本身就是一个渐进完成的过程,因此,通过动画来实现的滑动天然就具有弹性效果,这点从上述的属性动画的代码可看出。
2.如何利用动画特性实现弹性滑动效果?
由于动画的特性是在Duration的持续时间(例如1000ms)内,完成整个动画过程,利用这个特性,我们可以在动画的每一帧到来是获取动画已完成的比例,再根据这个比例计算出当前View所要滑动的距离。即mScrollX=dx*(动画已完成百分数%)。
可看如下代码实现,帮助理解:
由此提炼出用动画实现弹性滑动的思想:通过改变百分比,配合srollTo()方法来完成View的滑动。此思想与Scroller类似,但与Scroller不同的是,“改变百分比”具体是怎么实现的这个方法不同。
final int startX=0;//滑动起始横坐标为0
final int deltaX=100;//在水平方向上滑动距离为100像素
ValueAnimator animator=ValueAnimator.ofInt(0,1).setDuration(1000);//动画持续时间为1000ms
animator.addUpdateListener(new AnimatorUpdateListener()){
@Override
public void onAnimationUpdate(ValueAnimator animator);
float fraction=animator.getAnimatedFraction();//已实现部分动画所占的百分数
mButton1.scrollTo(startX+(int)(deltaX*fraction),0); //当前需要滑动到的位置
}
};
animator.start();
}
Ps:
1.此处说的滑动与Scroller一样,也是指View内容的滑动,而非View本身。
2.拓展:只要在onAnimationUpdate()方法里加上我们想要的其他操作,那么我们就可以利用动画的这种方法来实现其他的动画效果。
二.使用延时策略实现弹性滑动
1.“使用延时策略”方法的核心思想是什么?描述具体如何实现?
延时策略的核心思想是:通过发送一系列延时消息,在每段延时消息里让View滑动一小段距离,这样一系列延时消息组合起来就达到了一种渐进式的效果。但由于系统的消息调度需要时间,因此,用延时策略实现弹性滑动的持续时间无法精确,是个大约数,例如:以下这段代码就是大约在1000ms内将View的内容向左移动了100像素。
//用Hanler的postDelayed()方法实现延时策略,从而实现弹性滑动
private static final int MESSAGE_SCROLL_TO=1;
private static final int Frame_count=30; //总共分为30个延时消息发送
private static final int DELAYED_TIME=33; //发送2个延时消息间的间隔时间
private int mCount=0;//记录已经发送的延时消息个数
@SuppressLint("HandlerLeark")
private Handler mHandler=new Handler(){
private void handleMessage(Message msg){
switch(msg.what){
case MESSAGE_SCROLL_TO:
mCount++;
if(mCount<=FRAME_COUNT){
float fraction=mCount/(float)FRAME_COUNT;//滑动的百分数
int scrollX=(int)(fraction*100);//要滑动到的距离
mButton.scrollTo(scrollX,0);
mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO,DELAYED_TIME);
}
break;
default:
break;
}
};
};
那么,“延时策略”具体是怎么实现弹性滑动的呢?
有2种方式:
(1) 可以使用Handler或View的postDelayed()方法:
通过postDelayed()来延时发送一个消息,然后在消息里进行View的滑动,接连不断地发送这种延时消息,从而实现弹性滑动的效果。
(2) 或者使用线程的sleep()方法:
通过在while(){}循环里不断地滑动View和sleep,最终实现弹性滑动的效果。
总结:
1.用Scroller、动画、延时策略实现弹性滑动的核心思想都是:把一次滑动细分为若干个小幅度的滑动,一步一步组合起来就实现了一次完成的弹性滑动。
2.三种方式计算每次小幅度滑动位置的方法都是按照:所占百分比*dx(总共要滑动的距离)
而三种方式的区别就在于计算百分比的方法不同:
(1)Scroller:(当前时间-滑动起始时间)/滑动持续时间
(2)动画:当前动画已播放的帧数/总的帧数
(3)延时策略:已发送延时消息个数/总的延时消息个数
3.三种方式都需要配合scrollTo方法才能具体完成View的滑动
4.三种方式所说的滑动都是对内容的滑动,而不是View本身