了解view的滑動必須要先了解以下幾個概念:
view的位置參數:
(1)、left、top、right、bottom分別表示view相對于父控件的左上頂點的坐標和右下頂點的坐標;分別通過getLeft()、getTop()、getRight()、getBottom()獲得。
(2)、x、y、translationX、translationY。x、y表示view的左上頂點的坐標;translationX、translationY表示view的左上頂點相對于父控件的偏移量。
(3)、getX()、getY()獲取的是相對于父控件的坐標;getRawX()、getRawY()獲取的是相對于手機屏幕的坐標。
TouchSlop:常量;和手機設備有關;表示系統所能識別的最小的滑動距離。可以通過ViewConfiguration.get(getContext()).getScaledTouchSlop()獲取;
由于手機屏幕小,所以需要通過滑動來對內容進行顯示和隱藏。view的滑動主要有三種方式:1、通過view的scrollTo/scrollBy方法實現;2、通過動畫給view進行平移操作;3、改變view的Layoutparmes參數,是view進行重新布局,實現滑動。
(1)、scrollTo/scrollBy:mScrollX是view的左邊緣和內容的左邊緣的距離;mScrollY是view的上邊緣和內容的上邊緣的距離。當view的左邊緣在內容的左邊緣的右邊的時候,mScrollX是正值;當view的上邊緣在內容的上邊緣的下邊時,mScrollY為正值;scrollTo和scrollBy方法不會改變view在布局中的位置,改變的是內容的位置。scrollTo()方法讓View相對于初始的位置滾動某段距離,scrollBy()方法則是讓View相對于當前的位置滾動某段距離。同時可以發現scrollBy()是通過scrollTo()方法實現的。
(2)、通過動畫:系統動畫并不能真正改變view的位置參數,如果希望動畫執行完后狀態得以保留,那么必須將fillAfter屬性設為true;使用屬性動畫就不會有這些問題,但是屬性動畫在android3.0無法使用,必須使用nineoldandroids兼容庫。注意使用兼容庫中的ViewHelper幫助類中的方法。
(3)、通過改變Layoutparmes:view.setLayoutParams();
彈性滑動:1、通過Scroller。2、通過動畫。3、通過延時策略。
首先看一下Scroller的典型用法:
mScroller.startScroll(scrollX, 0, deltaX, 0, 500);只是啟動滑動,但是控件并不會滑動,真正造成滑動的是下面的invalidate()方法,invalidate()的調用會使得view重繪,調用computeScroll()方法,在computeScroll()方法里面會判斷滑動是否結束,computeScrollOffset返回值為true表示滑動未結束,返回false表示滑動結束;滑動未結束的時候調用scrollTo()進行滑動,并調用invalidate(),如此循環直到computeScrollOffset返回true為止。
延時策略:通過Handler發送并接收延時消息,每次接收到消息便完成一次ScrollTo操作,從而實現彈性滑動的效果。但是需要注意的是,由于系統的消息調度需要時間,完成這次彈性滑動的時間總是大于if條件判斷為true的次數乘以20ms(延遲消息的發送時間間隔)。因此對彈性滑動完成總時間有精確要求的使用場景下,使用延時策略是一個不太合適的選擇。
public void handleMessage(Message msg) {
switch(mag.what){
case SCROLL_FRACTION:{
//if判斷滑動還沒有結束,結束則不再滑動和發送消息
if(){
//通過滑動完成比例計算該次滑動片段的位置點scrollX,scrollY
View.scrollTo(scrollX,scrollY);
mHandler.sendEmptyMessageDelayed(SCROLL_FRACTION, 20);
}
break;
}
default:
break;
}
}