多次触发 Scrollview 的 Android onScrollChanged

标签 android event-handling scrollview

我想在 Scrollview 上跟踪 ScrollY(不,我不能使用网格或列表)

我正在使用带有 onScrollChanges 监听器的 ViewTreeObserver。但是,它会被多次触发。更糟糕的是:当它被调用 4 次中的 3 次时, ScrollView 的 scrollY 是 0 和 1 次我得到正确的数量。然而,并不是每 4 次调用都是正确的,触发正确值的时刻是随机的,我需要能够听到滚动位置 0。

这是我用来观察我的 ScrollView 的代码:

mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {

        @Override
        public void onScrollChanged() {
           Log.d("StupidScrollView", "Scroll positionY: " + mScrollView.getScrollY());
        }
    });

示例输出:

 D/StupidScrollView﹕ Scroll positionY: 0
 D/StupidScrollView﹕ Scroll positionY: 0
 D/StupidScrollView﹕ Scroll positionY: 0
 D/StupidScrollView﹕ Scroll positionY: 77

我不得不提一下,我在一个 ViewPager 中,我的 fragment 包含一个需要观察的 Scrollview。不知何故,这听起来像是与此相关的问题。

最佳答案

我看到了你的问题,我自己在 ScrollView 方面遇到了很多麻烦。这是我在 ScrollView 中获取滚动值的解决方案(我为你添加了一个 System.out)。

首先创建一个扩展 ScrollView 的自定义类,并创建一个具有 onScrollChanged 方法的监听器,如下所示:

public class ProductDetailScrollView extends ScrollView {

    public interface OnScrollChangedListener {
        void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);
    }

    private OnScrollChangedListener mOnScrollChangedListener;

    public void setOnScrollChangedListener(OnScrollChangedListener listener) {
        mOnScrollChangedListener = listener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedListener != null) {
            mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }

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

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

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

然后我创建一个变量(在 Activity 中)mOnScrollChangedListener,并将其设置为 mScrollView 的监听器:

private ProductDetailScrollView.OnScrollChangedListener mOnScrollChangedListener = new ProductDetailScrollView.OnScrollChangedListener() {
    public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {

        System.out.println("Scrolled: " + t);

        //Parallax Effect on scroll
        if (t > 0) {
            final float newY = (t / 4.0f) * -1.0f;
            mProductImageContainer.setY(newY);
        } else {
            mProductImageContainer.setY(0.0f);
        }
    }
};

在我的例子中,“t”值是垂直滚动的变化量,“l”是水平滚动,“oldl”和“oldt”是 t 和 l 的旧值,所以如果你需要要知道它向上或向下滚动,您可以使用 if(oldt > t) 等。

然后你像这样在你的 ScrollView 中设置监听器:

mScrollView.setOnScrollChangedListener(mOnScrollChangedListener);

关于多次触发 Scrollview 的 Android onScrollChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24826319/

相关文章:

java - 我可以在哪里放置鼠标事件处理代码,以便它不妨碍但仍然可以操作对象?

ios - 改变方向时在 ScrollView 中显示索引图像的校正

android - 具有拉伸(stretch)复合可绘制对象的固定宽度 TextView

android - FragmentStatePagerAdapter中间如何添加Fragment

android - recreate() 后 onBackPressed 不调用

javascript - 我们可以在 Javascript 中命名事件处理程序吗?

android - 构建像纽约时报应用程序一样的 Android 状态栏

typescript - $event 对象在 Angular 2 中究竟做了什么?

xamarin.ios - 单点触控 : how to optimize the performance for manual load the NIB

ios - 无法在 ScrollView 中嵌入屏幕(我的第一次尝试)