[英]Detect end of fling on ScrollView
I've overridden ScrollView
to pass MotionEvent
s to a GestureDetector
to detect fling events on the ScrollView. 我重写ScrollView
通过MotionEvent
s到一个GestureDetector
来检测了滚动一扔事件。 I need to be able to detect when the scrolling stops. 我需要能够检测到滚动停止的时间。 This doesn't coincide with the MotionEvent.ACTION_UP
event because this usually happens at the start of a fling gesture, which is followed by a flurry of onScrollChanged()
calls on the ScrollView. 这与MotionEvent.ACTION_UP
事件不一致,因为这通常发生在onScrollChanged()
手势的开始,随后是ScrollView上的一连串onScrollChanged()
调用。
So basically what we are dealing with here is the following events: 所以基本上我们在这里处理的是以下事件:
There's no callback for when the onScrollChanged events are done firing. 触发onScrollChanged事件时没有回调。 I was thinking of posting a message to the event queue using a Handler
during onFling and waiting for the Runnable
to execute to signal the end of the fling, unfortunately it fires after the first onScrollChanged call. 我想在onFling期间使用Handler
向事件队列发送消息,并等待Runnable
执行以指示fling的结束,不幸的是它在第一次onScrollChanged调用之后触发。
Any other ideas? 还有其他想法吗?
I've combined a few of the answers from here to construct a working listener that resembles the way AbsListView
does it. 我结合了这里的一些答案来构建一个类似于AbsListView
的工作方式的工作监听器。 It's essentially what you describe, and it works well in my testing. 它基本上就是你所描述的,它在我的测试中运作良好。
Note: you can simply override ScrollView.fling(int velocityY)
rather than use your own GestureDetector
. 注意:您可以简单地覆盖ScrollView.fling(int velocityY)
而不是使用您自己的GestureDetector
。
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class CustomScrollView extends ScrollView {
private static final int DELAY_MILLIS = 100;
public interface OnFlingListener {
public void onFlingStarted();
public void onFlingStopped();
}
private OnFlingListener mFlingListener;
private Runnable mScrollChecker;
private int mPreviousPosition;
public CustomScrollView(Context context) {
this(context, null, 0);
}
public CustomScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScrollChecker = new Runnable() {
@Override
public void run() {
int position = getScrollY();
if (mPreviousPosition - position == 0) {
mFlingListener.onFlingStopped();
removeCallbacks(mScrollChecker);
} else {
mPreviousPosition = getScrollY();
postDelayed(mScrollChecker, DELAY_MILLIS);
}
}
};
}
@Override
public void fling(int velocityY) {
super.fling(velocityY);
if (mFlingListener != null) {
mFlingListener.onFlingStarted();
post(mScrollChecker);
}
}
public OnFlingListener getOnFlingListener() {
return mFlingListener;
}
public void setOnFlingListener(OnFlingListener mOnFlingListener) {
this.mFlingListener = mOnFlingListener;
}
}
Thank you @PaulBurke +1 谢谢@PaulBurke +1
using Android.Content;
using Android.Runtime;
using Android.Util;
using Android.Widget;
using System;
public class CustomScrollView : ScrollView
{
public event EventHandler FlingEnded;
public event EventHandler FlingStarted;
private Action ScrollChecker;
private int PreviousPosition;
private const int DELAY_MILLIS = 100;
public CustomScrollView(Context context) : base(context) => Init();
public CustomScrollView(Context context, IAttributeSet attrs) : base(context, attrs) => Init();
public CustomScrollView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) => Init();
public CustomScrollView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes) => Init();
public CustomScrollView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }
private void Init()
{
ScrollChecker = () =>
{
int position = ScrollY;
if (PreviousPosition - position == 0)
{
FlingEnded?.Invoke(this, new EventArgs());
RemoveCallbacks(ScrollChecker);
}
else
{
PreviousPosition = ScrollY;
PostDelayed(ScrollChecker, DELAY_MILLIS);
}
};
}
public override void Fling(int velocityY)
{
base.Fling(velocityY);
FlingStarted?.Invoke(this, new EventArgs());
Post(ScrollChecker);
}
}
Usage: 用法:
myCustomScrollView.FlingEnded += myCustomScrollView_FlingEnded;
protected void myCustomScrollView_FlingEnded(object sender, EventArgs e) =>
{
//Do onFlingEnded code here
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.