So this is just some theoretical pseudo-code, but wouldn't something like this work?
I think the accepted answer doesn't really work the resolution is super low (i.e. you only get a velocity after an item has been scrolled off the entire screen, but what if you have large item views?).
int mTrackingPosition = -1;
int mLastTop;
long mLastEventTime;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Get a new tracking position if our old one is no longer on screen
// (this also includes the first time)
if (first > mTrackingPosition || last < mTrackingPosition) {
// We get the middle position here since that's likely to stay
// on screen for a bit when scrolling up or down.
mTrackingPosition = firstVisibleItem + visibleItemCount / 2;
// Reset our times since we can't really get velocity from this
// one measurement
mLastTop = mLastEventTime = -1;
// Handle the case that this happens more than once in a
// row if that's even reasonably possible (i.e. they
// scrolled rediculously fast)
}
// Get the measurements of the tracking view
View v = view.getViewForPosition(mTrackingPosition);
int top = v.getTop();
long time = System.currentTimeMillis();
// We can only get speed if we have a last recorded time
if (mLastTop != -1 && mLastEventTime != -1) {
// Velocity = distance / time
float velocity = (mLastTop - top) / (time - mLastEventTime);
// What do you want to do with the velocity?
...
}
// Update the last top and time so that we can track the difference
mLastTop = top;
mLastEventTime = time;
}
Again this is just pseudo-code that I haven't tested, but I think it should work. You'll also have to reset the last time and top position values when the scroll state is STATE_IDLE
.