Scroller平滑滾動
標籤: Android
在我們做Android應用時,特別是自定義View時,經常要做一些動畫。我們主要是有View動畫和屬性動畫以及藉助Scoller類來實現View的平滑移動。現在主要來學習Scroller類的應用。
預備知識:
關於Scroller,我們首先要了解,我們滑動的是這個View的內容,而View本身位置是不能改變的。我們需要知道View的mScrollX和mScrollY這兩個屬性,這兩個屬性我們可以通過getScrollX()和getScrollY()分別得到。在滑動過程中,mScrollX表示View的左邊緣和View內容左邊緣在水平方向的距離。我們都知道View的位置,是由View的四個頂點的位置決定的。當View從左向右滑動時,mScrollX為負值,反之為正。當View從上向下滑動時,mScrollY為負值,反之為正。
現在我們來看Scroller的最基本的用法:
1.實現構造器
public Scroller(Context context) {
this(context, null);
}
public Scroller(Context context, Interpolator interpolator) {
this(context, interpolator,
}
2.然後在需要滾動的時候,呼叫Scroller的startScroll()方法:
sample:在1000ms內水平滑至destX處。
private void smoothScoller(int destX,int destY){
int scrollX = getScrollX();
int dx = destX - scrollX;
mScoller.startScroll(scrollX,0,dx,0,1000);
invalidate();
}
3.實現View的computeScroll()方法:
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
這三步是Scroller的最基本的使用方法。
我們首先來看看Scroller的startScroll()方法:
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
mMode = SCROLL_MODE;
mFinished = false;
mDuration = duration;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartX = startX;
mStartY = startY;
mFinalX = startX + dx;
mFinalY = startY + dy;
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
}
很簡單的一個方法,這個方法其實並沒有做些關於動畫實現的方法,僅僅只是儲存了我們傳入的引數:
startX、startY: 滑動的起始點位置,
dx、dy: 將要滑動的偏移量
duration: 動畫將要持續的時間
既然startScroll()不是實現動畫的具體實現,那麼答案肯定在computeScroll()!我們繼續來看:
在startScroll()方法後面,呼叫了invalidate()方法,會強制View重新繪製,繪製過程中會呼叫View的draw()方法,在draw()方法裡,又回撥用computeScroll()。在View的原始碼裡,computeScroll()是個空方法,因此我們必須自己實現這個方法,上面即是我們自己實現的方法。在這個方法裡,Scroller會獲取View的當前位置getCurrX()和getCurrY(),然後通過scrollTo()來實現滑動。最後又呼叫postInvalidate()方法實現View的二次重繪,然後Scroller繼續獲取當前的位置,並通過scrollTo()來滑動到新位置,如此反覆,直到整個滑動過程結束。
在此過程中,還呼叫了computeScrollOffset()方法。這個方法是返回一個boolean型,主要變現為:如果當前動畫已完成,則返回false;如果沒有完成,則會一直返回true。
public boolean computeScrollOffset() {
if (mFinished) {
return false;
}
int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
if (timePassed < mDuration) {
switch (mMode) {
case SCROLL_MODE:
...
...
...
break;
case FLING_MODE:
...
...
if (mCurrX == mFinalX && mCurrY == mFinalY) {
mFinished = true;
}
break;
}
}
else {
mCurrX = mFinalX;
mCurrY = mFinalY;
mFinished = true;
}
return true;
}
總結:
Scroller其實並不會實現View的滑動,它只是儲存View的位置資訊,然後配合View的computeScroll()方法,不斷的重繪View,並修改View的滑動位置,並通過scrollTo()來滑動到新位置,這樣不斷的重複的小幅度滑動,由此組成了View的平滑滾動。
相關文章
- 瀏覽器原生支援平滑滾動瀏覽器
- 遇到overflow: scroll不能平滑滾動怎麼解決?
- Smooze for Mac(滑鼠平滑滾動神器)1.9.26漢化版Mac
- 使用jQuery實現的平滑滾動輪播圖jQuery
- 如何在 pyqt 中使用動畫實現平滑滾動的 QScrollAreaQT動畫
- mac滑鼠平滑滾動工具:Mac Mouse Fix for Mac中文版Mac
- vue2.0使用vue-seamless-scroll實現表格平滑滾動Vue
- mac滑鼠平滑滾動神器:Smooze for Mac v1.9.26漢化版Mac
- Three.js 進階之旅:頁面平滑滾動-王國之淚 ?JS
- vue3.0使用vue3-seamless-scroll實現表格平滑滾動Vue
- 三種方式實現平滑滾動頁面到頂部的功能
- Mos 3.3.2 中文版 (讓滑鼠平滑滾動) 原生 M1 執行
- Qt列表等控制元件實現平滑滾動&deepin啟動器存在的問題QT控制元件
- Datatable Scroller (Server Side) Part:3ServerIDE
- 1分鐘搞定 Nginx 版本的平滑升級與回滾Nginx
- 直播帶貨原始碼,vue中點選按鈕平滑滾動到頁面某個div位置原始碼Vue
- div滾動條樣式,水平滾動
- RecyclerView滾動位置,滾動速度設定View
- 隱藏滾動條保留滾動效果
- css隱藏滾動條並可以滾動CSS
- 移動端div跟隨滾動條滾動(自制
- Flutter滾動動畫Flutter動畫
- 入門Kubernetes - 滾動升級/回滾
- react滾動屏React
- 文字向上滾動
- Flutter 滾動監聽及實戰appBar滾動漸變FlutterAPP
- 直播商城原始碼,vue 彈窗 慣性滾動 加速滾動原始碼Vue
- 直播平臺製作,禁止頁面滾動 / 滾動事件穿透事件穿透
- Flutter 滾動控制元件篇-->滾動監聽及控制(ScrollController)Flutter控制元件Controller
- css實現隱藏滾動條並可以滾動內容CSS
- 如何讓VB6程式碼編輯器垂直滾動條隨滑鼠滾輪滾動
- 移動端模擬滾動
- js無縫滾動JS
- vue文字滾動元件Vue元件
- CSS滾動條美化CSS
- 論移動裝置內容的橫向滾動和豎向滾動
- angular 監聽 Windows 滾動事件 實現頁面滾動載入AngularWindows事件
- 解決移動端滾動穿透穿透
- 頁面圖片自動滾動