上次讲述了Scroller,今天继续整理View的另外两种弹性滑动方式,并对三种方式加以总结对比异同点。

一.利用动画特性实现类似于Scroller的弹性滑动效果

1.如何用动画实现滑动?

   使用动画来实现滑动实质上是让一个View进行平移,而平移就是一种滑动,其主要操作的是View的translationX和translationY这两个属性,动画有两种方式。

(1)View动画

   例如下面代码实现:在100ms内将一个View从原位置向右下角移动100个像素(图片系《Android开发艺术探索》书中的代码)

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本身