android 如何在NestedScrollView中停止正在进行的滚动?

f0ofjuux  于 2023-02-27  发布在  Android
关注(0)|答案(2)|浏览(825)

我有一个按钮,可以自动返回到顶部位置进入嵌套滚动视图。当滚动不在进行中时,它的工作原理就像一个魅力,否则如果当前滚动还在进行中,滚动到顶部,但直接滚动一点点燃后,刚刚...
我写了这个方法:

private void scrollToTop() {
        mScrollView.stopNestedScroll();
        mScrollView.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScrollView.scrollTo(0, 0);
            }
        }, 50);
    }

你有一些想法的家伙停止当前滚动并立即转到顶部?
非常感谢

b4lqfgs4

b4lqfgs41#

正确的方法是在你滚动时拦截用户的触摸。这需要你扩展ScrollView覆盖scrollToonInterceptTouchEvent方法,并且在列表滚动时禁用用户触摸,在滚动完成后返回触摸。
所以序列应该是这样的:
1.调用scrollTo滚动到指定位置
1.启用标志以
禁用触摸事件并开始滚动
1.滚动完成且状态变为
空闲**禁用标志时
附言:我可以提供代码的例子,但似乎你有更多的专业知识比我在写代码。干杯!
下面是一个代码片段:

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;
            }
        }
    }
}
mgdq6dx1

mgdq6dx12#

一个棘手的解决方案

private void scrollToTop() {
    mScrollView.stopNestedScroll();
    mScrollTop = true
    mScrollView.postDelayed(new Runnable() {
        @Override
        public void run() {
            mScrollView.scrollTo(0, 0);
        }
    }, 50);
}

此方法保持不变,检测滚动和滚动到达顶部(Kotlin代码)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        scrollView.setOnScrollChangeListener { scrollView, scorllX, scrollY, oldScrollX, oldScrollY ->
            scrollTop()
        }
    } else {
        scrollView.viewTreeObserver.addOnScrollChangedListener {
            scrollTop()
        }
    }
    private fun scrollTop() {
        if(mScrollTop) {
            if(scrollView.scrollY == 0){
               mScrollTop = false
            } else {
               scrollView.fullScroll(View.FOCUS_UP)
            }
        }
    }

相关问题