Reputation: 15635
I have a ListView
with about 100 entries. When the user does the "fling" from bottom to top it starts scrolling and keeps on scrolling even when the finger does not touch the display any more.
Is there a way to stop the scrolling animation at this point?
Upvotes: 3
Views: 8820
Reputation: 69
if you what disable default animation from list view just need set id for root (main) layout in xml and call void onClickListener in class for root layout
Upvotes: 0
Reputation: 671
and we lookup the android source code (AbsListView), give it a ACTION_CANCEL touchEvent, can stop the fling. it is easy.
listView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));
Upvotes: 16
Reputation:
You can prevent flinging for ListViews in API 8 by overriding onTouchEvent and calling smoothScrollBy.
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
this.smoothScrollBy(0, 0);
break;
}
return super.onTouchEvent(ev);
}
This takes over from the fling scrolling and scrolls 0px instead.
Upvotes: 3
Reputation: 8787
I didn't try the solution of Pompe de velo
but since smoothScrollToPosition()
is not available for API level less than 8 this didnt work for me.
I agree, changing default behaviour is not a good Idea, but sometimes you need to. So here is my (dirty) solution which uses reflection. This is by far not the recommended way since it's a hack but it works for me. There might be a better solution but I didn't found it.
class StopListFling {
private static Field mFlingEndField = null;
private static Method mFlingEndMethod = null;
static {
try {
mFlingEndField = AbsListView.class.getDeclaredField("mFlingRunnable");
mFlingEndField.setAccessible(true);
mFlingEndMethod = mFlingEndField.getType().getDeclaredMethod("endFling");
mFlingEndMethod.setAccessible(true);
} catch (Exception e) {
mFlingEndMethod = null;
}
}
public static void stop(ListView list) {
if (mFlingEndMethod != null) {
try {
mFlingEndMethod.invoke(mFlingEndField.get(list));
} catch (Exception e) {
}
}
}
}
Upvotes: 9
Reputation: 26925
My opinion is that you shouldn't modify this behaviour, since the fling behaviour is what the user expects.
However, to your question. I haven't tried this but in theory it should work.
Implement an OnScrollListener
to your ListView
and use the onScrollStateChanged()
method to check if the current state is SCROLL_STATE_FLING
. After you've determined that the scrolling perfoms by a fling you can get your ListView
's first visible position by using the getFirstVisiblePosition()
method and from there you can use smoothScrollToPosition()
where you put in your getFirstVisiblePosition()
value as an argument.
Upvotes: 0
Reputation: 28541
Well there surely is a way to do it. But the point is more whether or not it is advisable to do it, in my opinion.
The list is a standard Android control that behaves constistently across all applications. So I would be surprised if I found a list that did not behave the same in your application. You can stop the fling by putting your finger back on the screen at any time.
That said, if you want to do extra work, you could subclass the list view and override its on touch method. Best way to know what to do is to get the source code of ListView (ListView in Android 1.6).
Upvotes: 3