当前位置: 首页 > 知识库问答 >
问题:

我可以使用onScrollListener进行ScrollView吗?

南宫才艺
2023-03-14

我在布局中使用水平滚动视图,我需要确定用户已到达滚动的起点和终点。

对于ListView,我尝试了onScrollListener,可以找到滚动的开始和终端。

我试图在我的Scrollview中做同样的事情,但似乎不可能。还有其他可能的方法来实现我的需求吗?

共有3个答案

王成化
2023-03-14

这是我编写的派生的横向滚动视图,用于处理有关滚动和滚动结束的通知。当用户停止主动滚动时,以及在用户放手后完全减速时,它会正确处理:

public class ObservableHorizontalScrollView extends HorizontalScrollView {
    public interface OnScrollListener {
        public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);
        public void onEndScroll(ObservableHorizontalScrollView scrollView);
    }

    private boolean mIsScrolling;
    private boolean mIsTouching;
    private Runnable mScrollingRunnable;
    private OnScrollListener mOnScrollListener;

    public ObservableHorizontalScrollView(Context context) {
        this(context, null, 0);
    }

    public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ObservableHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        if (action == MotionEvent.ACTION_MOVE) {
            mIsTouching = true;
            mIsScrolling = true;
        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            if (mIsTouching && !mIsScrolling) {
                if (mOnScrollListener != null) {
                    mOnScrollListener.onEndScroll(this);
                }
            }

            mIsTouching = false;
        }

        return super.onTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
        super.onScrollChanged(x, y, oldX, oldY);

        if (Math.abs(oldX - x) > 0) {
            if (mScrollingRunnable != null) {
                removeCallbacks(mScrollingRunnable);
            }

            mScrollingRunnable = new Runnable() {
                public void run() {
                    if (mIsScrolling && !mIsTouching) {
                        if (mOnScrollListener != null) {
                            mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);
                        }
                    }

                    mIsScrolling = false;
                    mScrollingRunnable = null;
                }
            };

            postDelayed(mScrollingRunnable, 200);
        }

        if (mOnScrollListener != null) {
            mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);
        }
    }

    public OnScrollListener getOnScrollListener() {
        return mOnScrollListener;
    }

    public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {
        this.mOnScrollListener = mOnEndScrollListener;
    }

}
江阳羽
2023-03-14

这可能非常有用。使用NestedScrollView而不是ScrollView。支持库23.1为NestedScrollView引入了一个OnScrollChangeListener。所以你可以这样做。

 myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
            //Do something
        }
    });
堵茂勋
2023-03-14

视图的每个实例都调用< code > getViewTreeObserver()。现在,当保存< code>ViewTreeObserver的实例时,可以使用< code > addOnScrollChangedListener()方法向其添加< code > OnScrollChangedListener()。

您可以在此处查看有关此类的更多信息。

它让你知道每一个滚动事件——但是没有坐标。不过,您可以从侦听器中使用< code>getScrollY()或< code>getScrollX()来获取它们。

scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        int scrollY = rootScrollView.getScrollY(); // For ScrollView
        int scrollX = rootScrollView.getScrollX(); // For HorizontalScrollView
        // DO SOMETHING WITH THE SCROLL COORDINATES
    }
});
 类似资料:
  • 问题内容: 我们可以将其用于 (Android开放源代码项目) 开发吗,有没有办法做到这一点。我没有找到一个。有人对此有任何想法吗? 问题答案: 您可以将Android Studio用作AOSP的IDE,因为它只是InteliJ IDE的修改版本。 从AOSP根目录: 然后只需在Android Studio中“打开项目”,然后选择它生成的android.ipr。

  • 我有一个服务,它接收请求,生成电子邮件,将电子邮件保存到消息队列(由其他微服务发送)并返回HttpStatus.ok。我想测试一下,对于不同的请求,一个相关的电子邮件将被生成。 在这样的功能测试中使用Pact有意义吗? 有人知道类似的用法吗? 有没有其他的技术(最好是.NET Core中的技术)可以进行类似的测试? 我也在考虑https://github.com/approvals/approva

  • 我们可以使用页面对象执行滚动吗? 实际上,我需要根据元素滚动网页(向上/向下)。如何使用页面对象执行。 我使用Selenium web drive来启动浏览器,并使用Page对象来自动化web页面。 有什么建议吗???

  • 问题内容: 您如何自动化集成测试?我将JUnit用于其中一些测试。这是解决方案之一,还是完全错误?你有什么建议? 问题答案: JUnit可以工作。没有任何限制将其限制为仅单元测试。我们使用JUnit,Maven和CruiseControl来执行CI。 可能有一些特定于集成测试的工具,但我认为它们的用处取决于所集成的系统组件的类型。JUnit可以很好地用于非UI类型测试。

  • 问题内容: 在linux下,我可以使用GDB调试当前正在运行的进程吗? 问题答案: 是。使用命令。查看此链接以获取更多信息。打字在GDB控制台提供了以下: 附加到GDB外部的进程或文件。该命令附加到另一个目标,该目标与上一个“ ”命令的类型相同(“ ”将显示目标堆栈)。该命令可以将进程ID,进程名称(带有可选的进程ID作为后缀)或设备文件作为参数。对于进程ID,您必须具有向该进程发送信号的权限,并

  • 我有一个chrome扩展(不是App),它是来自免费第三方的数据的混搭。我没有为我的扩展维护服务器。 我可以使用Google drive通过用户帐户保存用户数据,以便在不同的计算机上共享吗?