一、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/n/256430.html