How to get the scroll speed on a ListView?
How to get the scroll speed on a ListView?
I have a ListView with onScrollStateChanged and onScroll event listeners. I want to be able to get the scroll speed of the ListView or some way to get the finalX location of the initiated scroll in some Event listener. Our app targets SDK version 7.
I need to measure or get the speed at which the ListView is scrolling.
Answer by QuickNick for How to get the scroll speed on a ListView?
Try it:
private class SpeedMeterOnScrollListener implements OnScrollListener { private long timeStamp; private int lastFirstVisibleItem; public SpeedMeterOnScrollListener() { timeStamp = System.currentTimeMillis(); lastFirstVisibleItem = 0; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { long lastTime = System.currentTimeMillis(); //calculate speed by firstVisibleItem, lastFirstVisibleItem, timeStamp and lastTime timeStamp = lastTime; lastFirstVisibleItem = firstVisibleItem; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } }
Answer by Angie for How to get the scroll speed on a ListView?
you can use android:fastScrollEnabled="true"
in you and don't forget to : YourListView.requestFocusFromTouch();
after yourAdapter.notifyDataSetChanged();
because it (yourlistview) lose the focus in fast speed
Answer by Scarmysun for How to get the scroll speed on a ListView?
Division first visible items difference on time difference is not a good solution. OnScroll listener recieves onScroll event every fixed period of time, so in most cases the result of division will be "0".
So you can try something like this:
private OnScrollListener onScrollListener = new OnScrollListener() { private int previousFirstVisibleItem = 0; private long previousEventTime = 0; private double speed = 0; @Override public void onScroll(HtcAbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (previousFirstVisibleItem != firstVisibleItem){ long currTime = System.currentTimeMillis(); long timeToScrollOneElement = currTime - previousEventTime; speed = ((double)1/timeToScrollOneElement)*1000; previousFirstVisibleItem = firstVisibleItem; previousEventTime = currTime; Log.d("DBG", "Speed: " +speed + " elements/second"); } } @Override public void onScrollStateChanged(HtcAbsListView view, int scrollState) { } };
Answer by rharter for How to get the scroll speed on a ListView?
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
.
Answer by Autobots for How to get the scroll speed on a ListView?
There is a simple way to get the speed (NOT Velocity) of the ListView, but it's not the perfect way.
/** The scroll speed threshold, it's a empiric value. */ private static final int LOW_SPEED_SCROLL_THRESHOLD = 3000; /** The offset, in pixels, by which the content of this view is scrolled vertically. */ private long mScrollY = 0; /** The last offset, in pixels, by which the content of this view is scrolled vertically. */ private long mLastScrollY = 0; /** The last scroll time, in millisecond */ private long mLastTime = 0; public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { final View currentItemView = absListView.getChildAt(0); if (currentItemView != null) { // The first try to scroll, reset the last time flag if (mLastTime == 0) { mLastTime = System.currentTimeMillis(); return; } final int height = currentItemView.getHeight(); final int currentPos = firstVisibleItem; final int currentPosOffset = currentItemView.getTop(); // < 0 mScrollY = currentPos * height - currentPosOffset; final long deltaOffset = mScrollY - mLastScrollY; final long currTime = System.currentTimeMillis(); if (currTime == mLastTime) { return; } final long speed = deltaOffset * 1000 / (currTime - mLastTime); if (Math.abs(speed) < LOW_SPEED_SCROLL_THRESHOLD) { // low speed } else { // high speed } mLastTime = currTime; mLastScrollY = mScrollY; } else { resetScrollState(); } } private void resetScrollState() { mLastTime = 0; mScrollY = 0; mLastScrollY = 0; }
- The perfect way is to use current scroll Velocity when callback
onScroll
?in AbsListView, we can get the velocity with FlingRunnable#mScroller.getCurrVelocity(), but unfortunately?theAbsListView
doesn't provide the public method ofgetCurrVelocity()
? so if we want to get this method, there are two methods to get it- Reflect this method, but I think it has the performance problem when get it
onScroll
callback - Copy the AbsListView.java source and create a new class of AbsListViewEx, provide a public method of
getCurrVelocity()
in this class, let new ListViewEx extends from AbsListViewEx, but it also has some problem: 1) it maybe a complex thing 2) the ListViewEx may has compatibility problem. However, this way I think is better thanReflect method
.
- Reflect this method, but I think it has the performance problem when get it
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment