首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >安卓:检测ScrollView何时停止滚动

安卓:检测ScrollView何时停止滚动
EN

Stack Overflow用户
提问于 2011-11-18 19:39:42
回答 12查看 94.1K关注 0票数 88

我在安卓系统中使用了ScrollView,其中ScrollView的可见部分与Scrollview中的一个单元格的大小相同。每个“单元格”的高度都是一样的。所以我要做的就是在ScrollView被滚动后捕捉到合适的位置。

目前,我正在检测用户何时触摸了ScrollView,以及何时开始滚动并从那里开始工作,但这是相当错误的。当用户只需轻拍它,它就会滚动然后减速,它也需要工作。

在iPhone上有一个类似于didDecelerate的函数,当ScrollView滚动完成后,我可以在那里做任何我想做的代码。Android有这样的功能吗?或者有没有一些代码我可以看一下,以找出一种更好的方法?

我浏览了Android文档,但找不到任何类似的东西。

EN

回答 12

Stack Overflow用户

发布于 2013-01-21 00:53:20

这是对ScrollView中丢失的OnEndScroll事件错误的另一个修复。

它的灵感来自hambonious answer。只需将这个类拖放到您的项目中(更改包以匹配您自己的包),并使用以下xml

代码语言:javascript
复制
package com.thecrag.components.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class ResponsiveScrollView extends ScrollView {

    public interface OnEndScrollListener {
        public void onEndScroll();
    }

    private boolean mIsFling;
    private OnEndScrollListener mOnEndScrollListener;

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

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

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

    @Override
    public void fling(int velocityY) {
        super.fling(velocityY);
        mIsFling = true;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
        super.onScrollChanged(x, y, oldX, oldY);
        if (mIsFling) {
            if (Math.abs(y - oldY) < 2 || y >= getMeasuredHeight() || y == 0) {
                if (mOnEndScrollListener != null) {
                    mOnEndScrollListener.onEndScroll();
                }
                mIsFling = false;
            }
        }
    }

    public OnEndScrollListener getOnEndScrollListener() {
        return mOnEndScrollListener;
    }

    public void setOnEndScrollListener(OnEndScrollListener mOnEndScrollListener) {
        this.mOnEndScrollListener = mOnEndScrollListener;
    }

}

再次更改包名称以匹配您的项目

代码语言:javascript
复制
<com.thecrag.components.ui.ResponsiveScrollView
        android:id="@+id/welcome_scroller"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/welcome_scroll_command_help_container"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/welcome_header_text_thecrag"
        android:layout_margin="6dp">
    ....
</com.thecrag.components.ui.ResponsiveScrollView>
票数 23
EN

Stack Overflow用户

发布于 2012-03-27 01:20:41

我将(Horizontal)ScrollView子类化,并做了如下操作:

代码语言:javascript
复制
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
    if (Math.abs(x - oldX) > SlowDownThreshold) {  
        currentlyScrolling = true;
    } else {
        currentlyScrolling = false;
        if (!currentlyTouching) {
            //scrolling stopped...handle here
        }
    }
    super.onScrollChanged(x, y, oldX, oldY);
}

我使用值1作为SlowDownThreshold,因为它似乎总是与上一个onScrollChanged事件的差值。

为了让它在缓慢拖动时正确运行,我必须这样做:

代码语言:javascript
复制
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            currentlyTouching = true;
    }
    return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouch(View view, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            currentlyTouching = false;
            if (!currentlyScrolling) {
                //I handle the release from a drag here
                return true;
            }
    }
    return false;
}
票数 9
EN

Stack Overflow用户

发布于 2014-07-22 17:13:15

我的方法是通过每次调用onScrollChanged()时更改的时间戳来确定滚动状态。很容易确定滚动的开始和结束时间。您还可以更改阈值(我使用100ms )来修复灵敏度。

代码语言:javascript
复制
public class CustomScrollView extends ScrollView {
    private long lastScrollUpdate = -1;

    private class ScrollStateHandler implements Runnable {

        @Override
        public void run() {
            long currentTime = System.currentTimeMillis();
            if ((currentTime - lastScrollUpdate) > 100) {
                lastScrollUpdate = -1;
                onScrollEnd();
            } else {
                postDelayed(this, 100);
            }
        }
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (lastScrollUpdate == -1) {
            onScrollStart();
            postDelayed(new ScrollStateHandler(), 100);
        }

        lastScrollUpdate = System.currentTimeMillis();
    }

    private void onScrollStart() {
        // do something
    }

    private void onScrollEnd() {
        // do something
    }

}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8181828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档