一、VelocityTracker簡介
VelocityTracker是Android提供的一個用於獲取手勢速度屬性的工具類,用於跟蹤觸摸事件的速度。在實際應用中,我們可以利用VelocityTracker獲取用戶手指在屏幕上的滑動速度,並進一步優化滑動體驗。例如,我們可以通過拖動屏幕實現ListView和RecyclerView的滑動,通過手指拖動實現ScrollView和ViewPager的滑動等操作。
二、VelocityTracker使用方法
使用VelocityTracker非常簡單,我們只需要在完成ACTION_DOWN、ACTION_MOVE和ACTION_UP事件後,調用VelocityTracker的computeCurrentVelocity方法即可計算當前手勢的速度值。具體代碼實現如下:
private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mVelocityTracker.clear(); mVelocityTracker.addMovement(event); break; case MotionEvent.ACTION_MOVE: mVelocityTracker.addMovement(event); mVelocityTracker.computeCurrentVelocity(1000); float velocityX = mVelocityTracker.getXVelocity(); float velocityY = mVelocityTracker.getYVelocity(); break; case MotionEvent.ACTION_UP: mVelocityTracker.clear(); break; case MotionEvent.ACTION_CANCEL: mVelocityTracker.recycle(); break; } return super.onTouchEvent(event); }
上述代碼中,computeCurrentVelocity方法的參數1000代表在1秒內移動的像素數。通過getXVelocity和getYVelocity方法分別獲取水平和豎直方向的速度值。注意,在使用VelocityTracker之前,我們需要在Activity或Fragment生命周期結束時回收VelocityTracker對象,否則會造成內存泄漏。
三、VelocityTracker的性能問題
儘管VelocityTracker使用起來非常簡單,但是在實際開發中,我們需要注意VelocityTracker的性能問題。具體而言,VelocityTracker會記錄所有的滑動事件,如果滑動事件的數量過多,就會造成內存佔用過高的問題。特別是在ListView或RecyclerView中,當用戶快速滑動屏幕時,會產生大量的滑動事件,從而導致VelocityTracker佔用過多的內存。
四、優化VelocityTracker的性能
1、使用SparseArray集合代替HashMap
在使用VelocityTracker時,通常需要保存多個VelocityTracker對象,因為每個VelocityTracker對象只能用於跟蹤一個觸摸事件。因此,我們需要使用一個集合來保存多個VelocityTracker對象,在使用時進行獲取。一般來說,我們會選擇HashMap來保存VelocityTracker對象,但是在實際使用中,我們發現使用SparseArray集合可以更好地滿足我們的需求。
SparseArray是Android提供的一個優化版的HashMap,它的實現原理和HashMap類似,但是在某些場景下比HashMap更加高效。在使用SparseArray時,我們可以將觸摸事件的id作為key,將VelocityTracker對象作為value,從而可以快速地查找和回收所需的VelocityTracker對象。具體代碼如下:
private SparseArray mVelocityTrackers = new SparseArray(); @Override public boolean onTouchEvent(MotionEvent event) { int pointerId = event.getPointerId(event.getActionIndex()); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: VelocityTracker tracker = VelocityTracker.obtain(); tracker.addMovement(event); mVelocityTrackers.put(pointerId, tracker); break; case MotionEvent.ACTION_MOVE: VelocityTracker pointerTracker = mVelocityTrackers.get(pointerId); pointerTracker.addMovement(event); pointerTracker.computeCurrentVelocity(1000); float velocityX = pointerTracker.getXVelocity(); float velocityY = pointerTracker.getYVelocity(); break; case MotionEvent.ACTION_POINTER_DOWN: VelocityTracker newPointerTracker = VelocityTracker.obtain(); newPointerTracker.addMovement(event); mVelocityTrackers.put(pointerId, newPointerTracker); break; case MotionEvent.ACTION_POINTER_UP: // pointerIndex是被放下手指的序號 int pointerIndex = event.getActionIndex(); int pointerUpId = event.getPointerId(pointerIndex); VelocityTracker pointerUpTracker = mVelocityTrackers.get(pointerUpId); pointerUpTracker.recycle(); mVelocityTrackers.remove(pointerUpId); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: VelocityTracker upTracker = mVelocityTrackers.get(pointerId); upTracker.recycle(); mVelocityTrackers.remove(pointerId); break; } return super.onTouchEvent(event); }
上述代碼中,我們使用SparseArray集合代替了HashMap,從而可以更高效地查找和回收VelocityTracker對象。同時,在ACTION_POINTER_DOWN和ACTION_POINTER_UP事件中,我們需要對新添加的手指和釋放的手指分別進行VelocityTracker對象的創建和回收操作。
2、限制VelocityTracker記錄的滑動事件數量
為了避免VelocityTracker佔用過多的內存,我們可以限制它記錄的滑動事件的數量。由於VelocityTracker記錄的事件數量是由它自身的History記錄來決定的,因此我們可以通過限制History記錄來達到限制滑動事件數量的目的。但是需要注意的是,限制History記錄也會影響VelocityTracker計算速度值的精度。
具體實現方式為,我們可以在Activity或Fragment的onCreate方法中設置VelocityTracker使用的滑動事件緩存數量。例如,我們可以通過以下代碼設置滑動事件緩存數量為100:
private void setupVelocityTracker() { mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.setRetainSeconds(0); // 最多記錄100個事件 mVelocityTracker.setMaxEventPoolSize(100); }
3、盡量減少滑動事件數量
為了避免VelocityTracker佔用過多的內存,我們還可以盡量減少滑動事件數量。具體而言,我們可以通過以下方式來減少滑動事件的數量:
(1)、採用較大的緩存區域
在使用ListView、RecyclerView、ScrollView等控件時,我們可以設置它們的緩存區域較大。通過設置較大的緩存區域,可以減少滑動事件的數量,從而避免VelocityTracker佔用過多的內存。
// 設置ListView的緩衝區大小 mListView.setRecyclerListener(mRecycler); mListView.setScrollingCacheEnabled(true); mListView.setAnimationCacheEnabled(false);
(2)、減少刷新頻率
在ListView、RecyclerView、ScrollView等控件中,如果我們需要及時刷新視圖,會產生頻繁的滑動事件,從而導致VelocityTracker佔用過多的內存。如果我們在刷新視圖時,適當降低刷新頻率,就可以減少滑動事件的數量,從而優化VelocityTracker的性能。
總結
VelocityTracker是Android中非常實用的一個工具類,用於獲取手勢速度屬性。在使用VelocityTracker時,我們需要注意它的性能問題,特別是在ListView、RecyclerView、ScrollView等控件中滑動過程中,會產生大量的滑動事件,從而導致VelocityTracker佔用過多的內存。為了優化VelocityTracker的性能,我們可以使用SparseArray集合代替HashMap,限制VelocityTracker記錄的滑動事件數量,減少滑動事件數量等方式來達到優化的目的。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/256430.html