检测scrollView何时滚动

5

我想检测ScrollView何时完成滚动,以便稍微修改其位置。 以前,我使用ACTION_UP来检测用户何时放开手指,但后来我意识到这不允许我使用“flinging”,因为它会在滚动完成之前修改滚动。

有没有办法检测ScrollView何时完成滚动? 或者像ListView一样检测其滚动状态?

还有其他实现此目的的想法吗?

谢谢。


请尝试此链接:https://dev59.com/T2sy5IYBdhLWcg3w-zF4 - Shraddha
2个回答

3
我根据Jourbac评论实现了一个解决方案。
问候
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ScrollView;

public class MyScrollView extends ScrollView {

    private static final int WHAT = 1;

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(!hasMessages(WHAT)) {
                Log.i("TestScroll", "Last msg!. Position from " 
                                    + msg.arg1 + " to " + msg.arg2);                
            }
        }
    }

    private Handler mHandler = new MyHandler();

    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        final Message msg = Message.obtain();
        msg.arg1 = oldt;
        msg.arg2 = t;
        msg.what = WHAT;
        mHandler.sendMessageDelayed(msg, 500);
    }

}

这并没有解决提问者所问的问题 - 它只是在每次滚动更改时发送延迟消息。 - Warlax
当用户在半秒钟内完成滚动时,日志消息才会被打印。这解决了问题。 - Fede

1

我会通过创建一个ScrollView的子类,比如MyScrollView,并使用它来代替ScrollView来解决这个问题。

这样你就可以重写ScrollView的方法,在滚动时调用它们,并在其中添加一些回调(不要忘记调用相应的super方法)。

我无法确定ScrollView的哪些方法会被调用;我假设每次滚动发生时都会调用其中一个方法,但是哪一个呢...也许只是scrollTo()

我想重写所有这些方法并记录它们被调用的时间可能会是一个非常有趣和有收获的经验。如果我这样做了,我会回来提供更有用的答案,假设在那段时间内没有其他人提供了答案。


检查ScrollView的源代码似乎也是个好主意。我在那里找到了甜甜圈版本:http://www.netmite.com/android/mydroid/donut/frameworks/base/core/java/android/widget/ScrollView.java - 我看到scrollTo()的源代码有一个注释,说每次调用scrollBy()时都应该调用它 - 所以我倾向于首先重写scrollTo()。祝你阅读愉快 :-) - Joubarc
4
只需覆盖onScrollChanged()方法即可。 - Romain Guy
跟进一下:看起来如果我将代码放在重写的Fling和ScrollTo中,它会在滚动或飞掷时不断被调用,而不仅仅是在结束时。看起来我需要找到一种访问isFinished(位于scroller.java中)或其他检查滚动是否完成的方法... - Matt
嗯,我还是没有运气...也许它正在工作,只是我不知道?现在从重写的onScrollChanged中,唯一的代码是super和我的监听器代码:mOnScrollListener.onScrollFinished(this);其中onScrollListener是我的新视图类中的公共接口。现在该事件会在主活动中触发一个toast。当滚动/快速滑动时,这个toast会不断弹出,并在一段时间后消失。这让我想到它是在每次滚动更新时触发,而不是在所有操作完成后触发。 - Matt
我猜是这样的 - 从某种程度上讲,这是有道理的;当滚动真正完成时,它如何考虑呢?如果你紧接着又开始滚动了怎么办?因此,如果你真的需要知道,你需要自己实现一个计时器。也许使用Handler更容易 - 每次滚动事件触发时,使用PostDelayed(例如延迟1秒);你发布的可运行文件可以简单地检查队列中是否还有更多的消息。如果没有,那么在过去的一秒钟内没有发生更多的滚动事件,你可以做一些不同的事情。当我有时间时,我可能也会测试一下这个方法。 - Joubarc
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接