arn*_*rnp 134 android listener scrollview
我HorizontalScrollView在布局中使用a ,我需要确定用户已达到滚动的起点和终点.
因为ListView我已经尝试过了onScrollListener,可以找到滚动的起点和终点.
我尝试在我做同样的事情,Scrollview但似乎不可能.有没有其他可能的方法来实现我的需要.
提前致谢.
Zbu*_*bun 375
每个View调用实例getViewTreeObserver().现在,当持有实例时ViewTreeObserver,您可以OnScrollChangedListener()使用该方法添加一个实例addOnScrollChangedListener().
您可以在此处查看有关此课程的更多信息.
它可以让您了解每个滚动事件 - 但没有坐标.您可以通过使用getScrollY()或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
    }
});
Mid*_*mar 42
这可能非常有用.用NestedScrollView而不是ScrollView.支持库23.1引入了一个OnScrollChangeListener到NestedScrollView.所以你可以做这样的事情.
 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
        }
    });
ZaB*_*anc 17
这是我编写的派生的HorizontalScrollView,用于处理有关滚动和滚动结尾的通知.它可以在用户停止主动滚动时以及在用户放开后完全减速时正确处理:
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) {
            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;
    }
}
Cri*_*tan 11
您可以使用NestedScrollView代替ScrollView. 但是,当使用 Kotlin Lambda 时,它不会知道您想要 NestedScrollViewsetOnScrollChangeListener而不是 View(这是 API 级别 23)。您可以通过将第一个参数指定为 NestedScrollView 来解决此问题。
nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
    Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}
小智 6
如果你想知道一个视图的滚动位置,那么你可以在 View 类上使用以下扩展函数:
fun View?.onScroll(callback: (x: Int, y: Int) -> Unit) {
    var oldX = 0
    var oldY = 0
    this?.viewTreeObserver?.addOnScrollChangedListener {
        if (oldX != scrollX || oldY != scrollY) {
            callback(scrollX, scrollY)
            oldX = scrollX
            oldY = scrollY
        }
    }
}
小智 6
除了接受的答案外,您还需要持有听众的参考,并在不需要时将其删除。否则,您将收到 ScrollView 和内存泄漏的空指针异常(在已接受答案的评论中提到)。
您可以在您的活动/片段中实现 OnScrollChangedListener。
MyFragment : ViewTreeObserver.OnScrollChangedListener
当您的视图准备就绪时,将其添加到 scrollView。
scrollView.viewTreeObserver.addOnScrollChangedListener(this)
不再需要时删除侦听器(即 onPause())
scrollView.viewTreeObserver.removeOnScrollChangedListener(this)
| 归档时间: | 
 | 
| 查看次数: | 131927 次 | 
| 最近记录: |