Определить конец броска на ScrollView
Я переопределил ScrollView
пройти MotionEvent
с GestureDetector
обнаруживать события броска на ScrollView. Мне нужно быть в состоянии определить, когда прокрутка останавливается. Это не совпадает с MotionEvent.ACTION_UP
событие, потому что это обычно происходит в начале броска жеста, который сопровождается потоком onScrollChanged()
вызывает ScrollView.
Итак, в основном мы имеем дело со следующими событиями:
- onFling
- onScrollChanged, onScrollChanged, onScrollChanged,..., onScrollChanged
Нет обратного вызова, когда события onScrollChanged завершены. Я думал о публикации сообщения в очередь событий, используя Handler
во время полета и ожидания Runnable
выполнить, чтобы сигнализировать об окончании сброса, к сожалению, он срабатывает после первого вызова onScrollChanged.
Есть другие идеи?
2 ответа
Я соединил несколько ответов отсюда, чтобы создать работающего слушателя, который напоминает способ AbsListView
Является ли. По сути, это то, что вы описываете, и это хорошо работает в моем тестировании.
Примечание: вы можете просто переопределить 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;
}
}
Спасибо @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);
}
}
Использование:
myCustomScrollView.FlingEnded += myCustomScrollView_FlingEnded;
protected void myCustomScrollView_FlingEnded(object sender, EventArgs e) =>
{
//Do onFlingEnded code here
};