问题描述
由于某种原因,我有一个滚动视图女巫,我不想自动滚动!! 我想先测量滚动距离,然后进行一些计算,然后使用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);
}
}
1楼
不要修改滚动视图的行为。 引擎盖下有许多优化措施,可以使滚动平滑。 解决方法是,可以将透明视图覆盖在scrollView的顶部。 例如。 视图sOverlay覆盖在xml文件的scrollView顶部。 覆盖触摸监听器并返回false。 将手势侦听器和算法应用于sOverlay视图。 要了解scrollView将要执行的行程量,请获取scrollView的顶部位置Y1和scrollView的底部位置Y2 。
Y1 = scrollView.getScrollY();
Y2 = scrollView.getScrollY() + scrollView.getHeight();