Android 使用滚动视图时的onScroll手势

Android 使用滚动视图时的onScroll手势,android,android-scrollview,android-gesture,Android,Android Scrollview,Android Gesture,由于某些原因,我有一个滚动视图,我不想自动滚动!!我想先测量滚动距离,然后进行一些计算,然后使用scrollView.scrollBy()函数滚动。另外,当我到达scrollView的末尾时,我仍然希望捕获滚动手势。我无法使用scrollView滚动侦听器,因为 首先滚动发生,然后我会得到通知,而不是反过来 第二,如果我到了卷轴的末尾,我不知道我错过了多少卷轴。例如,如果我的滚动视图中有内容,我会滚动600px,但由于我快结束了,我只得到100px的滚动。我需要知道额外的500px做一些动画)

由于某些原因,我有一个滚动视图,我不想自动滚动!!我想先测量滚动距离,然后进行一些计算,然后使用scrollView.scrollBy()函数滚动。另外,当我到达scrollView的末尾时,我仍然希望捕获滚动手势。我无法使用scrollView滚动侦听器,因为

  • 首先滚动发生,然后我会得到通知,而不是反过来
  • 第二,如果我到了卷轴的末尾,我不知道我错过了多少卷轴。例如,如果我的滚动视图中有内容,我会滚动600px,但由于我快结束了,我只得到100px的滚动。我需要知道额外的500px做一些动画)。
我创建了一个没有滚动的自定义滚动视图,通过在触摸事件中不调用父对象。然后,我使用一个手势检测器来检测滚动的数量,并定义了一个监听器将这个距离发送回使用滚动视图的活动。然后我使用scrollview.scrollBy()来滚动该数量。除了屏幕滞后和滚动根本不顺畅之外,它都能正常工作!那么我在这里错过了什么? 这是我自定义滚动视图的代码

public class CustomScrollView extends ScrollView implements GestureDetector.OnGestureListener {

public interface ScrollGestureListener {
    void onScrollGesture(int dy);
}

private GestureDetectorCompat gestureDetector;
private ScrollGestureListener listener;


public CustomScrollView(Context context) {
    super(context);
    init();
}

public CustomScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init();
}


private void init(){
    gestureDetector = new GestureDetectorCompat(getContext(), this);
}

public void setScrollGestureListener(ScrollGestureListener listener) {
    this.listener = listener;
}

@Override
public boolean onInterceptTouchEvent(@NonNull MotionEvent ev) {
    boolean result = super.onInterceptTouchEvent(ev);
    if (gestureDetector.onTouchEvent(ev)) {
        return true;
    }
    else {
        return false;
    }
}

@Override
public boolean onTouchEvent(@NonNull MotionEvent ev) {
    gestureDetector.onTouchEvent(ev);
    return true;
    //return super.onTouchEvent(ev);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    SLog.d("l: " + l + " t: " + t);
}

@Override
public boolean onDown(MotionEvent event) {
//        SLog.d("onDown: " + event.toString());
    return true;
}

@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
                       float velocityX, float velocityY) {
//        SLog.d( "onFling: " + event1.toString() + event2.toString());
    return true;
}

@Override
public void onLongPress(MotionEvent event) {
//        SLog.d( "onLongPress: " + event.toString());
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                        float distanceY) {
    SLog.d( "onScroll: " + distanceY + " -- " + e1.toString()+e2.toString());

    if(listener != null)
        listener.onScrollGesture((int) distanceY);

    return true;
}

@Override
public void onShowPress(MotionEvent event) {
//        SLog.d( "onShowPress: " + event.toString());
}

@Override
public boolean onSingleTapUp(MotionEvent event) {
//        SLog.d( "onSingleTapUp: " + event.toString());
    return true;
}
这是我使用这个滚动视图的活动代码

public class TestActivity extends AppCompatActivity implements CustomScrollView.ScrollGestureListener {
private GestureDetectorCompat mDetector;
private CustomScrollView scrollView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    scrollView = (CustomScrollView) findViewById(R.id.test_scroll_view);
    scrollView.setScrollGestureListener(this);
}

@Override
public void onScrollGesture(int dy) {
    scrollView.smoothScrollBy(0, dy);
}

}

不要修改滚动视图的行为。引擎盖下有很多优化,可以使滚动平滑。 作为解决方案,您可以在scrollView的顶部覆盖一个透明视图。视图sOverlay覆盖在xml文件中滚动视图的顶部。覆盖触控式侦听器&返回false。在sOverlay视图上应用您的手势侦听器和算法。要了解scrollView将要执行的行程量,请获取scrollView的顶部位置Y1和底部位置Y2

Y1 = scrollView.getScrollY();
Y2 = scrollView.getScrollY() + scrollView.getHeight();