如何停止 NestedScrollView 中正在进行的滚动?
How to stop scroll in progress in NestedScrollView?
我有一个按钮可以自动 returns 到 NestedScrollView 的顶部位置。当滚动不在进行时,它就像一个魅力,否则如果当前滚动还在进行中,滚动会转到顶部,但在之后直接向下滚动一点点...
我写了这个方法:
private void scrollToTop() {
mScrollView.stopNestedScroll();
mScrollView.postDelayed(new Runnable() {
@Override
public void run() {
mScrollView.scrollTo(0, 0);
}
}, 50);
}
你们有没有停止当前滚动并立即返回顶部的想法?
非常感谢
正确的方法是在滚动时拦截用户的触摸实用。这将需要您扩展 ScrollView
覆盖 scrollTo
和 onInterceptTouchEvent
方法,并且 禁用 用户触摸,同时列表 滚动 , 滚动完成后返回触摸。
所以顺序是这样的:
- 调用
scrollTo
滚动到特定位置
- 启用标志以禁用触摸事件和开始滚动
- 当滚动完成并且状态更改为空闲 禁用标志
P.S:我可以提供代码示例,但看来您在编写代码方面比我更专业。干杯!
这里是一段代码:
import android.content.Context;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class MyScrollView extends NestedScrollView {
public static final int MAX_SCROLL_FACTOR = 1;
boolean isAutoScrolling;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void scrollTo(int x, int y) {
isAutoScrolling = true;
super.scrollTo(x, y);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (isAutoScrolling)
return super.onInterceptTouchEvent(event);
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isAutoScrolling)
return super.onTouchEvent(event);
return false;
}
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (isAutoScrolling) {
if (Math.abs(y - oldY) < MAX_SCROLL_FACTOR || y >= getMeasuredHeight() || y == 0
|| Math.abs(x - oldX) < MAX_SCROLL_FACTOR || x >= getMeasuredWidth() || x == 0) {
isAutoScrolling = false;
}
}
}
}
我有一个按钮可以自动 returns 到 NestedScrollView 的顶部位置。当滚动不在进行时,它就像一个魅力,否则如果当前滚动还在进行中,滚动会转到顶部,但在之后直接向下滚动一点点...
我写了这个方法:
private void scrollToTop() {
mScrollView.stopNestedScroll();
mScrollView.postDelayed(new Runnable() {
@Override
public void run() {
mScrollView.scrollTo(0, 0);
}
}, 50);
}
你们有没有停止当前滚动并立即返回顶部的想法?
非常感谢
正确的方法是在滚动时拦截用户的触摸实用。这将需要您扩展 ScrollView
覆盖 scrollTo
和 onInterceptTouchEvent
方法,并且 禁用 用户触摸,同时列表 滚动 , 滚动完成后返回触摸。
所以顺序是这样的:
- 调用
scrollTo
滚动到特定位置 - 启用标志以禁用触摸事件和开始滚动
- 当滚动完成并且状态更改为空闲 禁用标志
P.S:我可以提供代码示例,但看来您在编写代码方面比我更专业。干杯!
这里是一段代码:
import android.content.Context;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class MyScrollView extends NestedScrollView {
public static final int MAX_SCROLL_FACTOR = 1;
boolean isAutoScrolling;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void scrollTo(int x, int y) {
isAutoScrolling = true;
super.scrollTo(x, y);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (isAutoScrolling)
return super.onInterceptTouchEvent(event);
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isAutoScrolling)
return super.onTouchEvent(event);
return false;
}
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (isAutoScrolling) {
if (Math.abs(y - oldY) < MAX_SCROLL_FACTOR || y >= getMeasuredHeight() || y == 0
|| Math.abs(x - oldX) < MAX_SCROLL_FACTOR || x >= getMeasuredWidth() || x == 0) {
isAutoScrolling = false;
}
}
}
}