44

我只想检测底部的滚动嵌套scrollview android的位置,以及调用函数。我的代码是:

scroll.getViewTreeObserver()
      .addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
           @Override
           public void onScrollChanged() {
               int totalHeight = scroll.getChildAt(0).getHeight();
               int scrollY = scroll.getScrollY();
               Log.v("position", "totalHeight=" + totalHeight + "scrollY=" + scrollY);
               if (scrollY==totalHeight) {
                   getPlaylistFromServer("more");
               }
           }
      });

但总高度与 MAX ScrollY 不同。如何解决?

4

8 回答 8

112

设置setOnScrollChangeListener一个NestedScrollView参数来获取

  • NestedScrollView v(带滚动的父级)
  • 整数滚动Y
  • int oldScrollY

要检测偏移量是否在底部,需要获取内容高度的值,v.getChildAt(0).getMeasuredHeight()并比较当前滚动超过父级的高度,如果有相同的值,则表示已经到了结尾。

您可以使用父视图获取高度v.getMeasuredHeight()

NestedScrollView scroller = (NestedScrollView) findViewById(R.id.myScroll);

if (scroller != null) {

    scroller.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

            if (scrollY > oldScrollY) {
                Log.i(TAG, "Scroll DOWN");
            }
            if (scrollY < oldScrollY) {
                Log.i(TAG, "Scroll UP");
            }

            if (scrollY == 0) {
                Log.i(TAG, "TOP SCROLL");
            }

           if (scrollY == ( v.getMeasuredHeight() - v.getChildAt(0).getMeasuredHeight() )) {
               Log.i(TAG, "BOTTOM SCROLL");
           }
       }
    });
}
于 2016-06-04T12:10:00.187 回答
42

我知道已经晚了,但是..试试这种方式。

scroll.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
            View view = (View) scroll.getChildAt(scroll.getChildCount() - 1);

            int diff = (view.getBottom() - (scroll.getHeight() + scroll
                    .getScrollY()));

            if (diff == 0) {
                getPlaylistFromServer("more");
            }          
    }
});

快乐编码..

于 2016-06-03T04:54:27.743 回答
8

Webserve 的回答是正确的,但它需要在 onScrollChange(覆盖方法)中进行一些更改,如下所示:

if (scrollY === v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()) {
   // end of the scroll view
}

科特林:

if (scrollY == v.getChildAt(0).measuredHeight - v.measuredHeight) {
    // end of the scroll view
}
于 2019-04-29T04:17:20.810 回答
6
  @Override
public void onScrollChange(NestedScrollView nestedScrollView, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
    if (nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1) != null) {
        if ((scrollY >= (nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1).getMeasuredHeight() - nestedScrollView.getMeasuredHeight())) &&
                scrollY > oldScrollY) {
            LogsUtils.INSTANCE.makeLogD(">onScrollChange>", ">>BOTTOm");
        }

    }
}

它对我有用, 来源

于 2018-12-06T10:34:58.130 回答
2

这对我有用:

nestedScroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

            if (v.getChildAt(0).getBottom()<=(nestedScroll.getHeight()+scrollY)) {
                System.out.println("End of NestedScrollView");
            }

        }
    });

基本上,我们在一个nestedScrollView 中添加了许多视图,但将它们以单一视图的形式包装在一起。因此,childCount 将始终为 1,其索引为 0。因此,用于v.getChildAt(0).getBottom()确定其底部。现在,nestedScroll.getHeight()以像素为单位返回高度,并且,scrollY将返回当前垂直原点。因此,每次到达 NestedScrollView 的底部时,上述条件都会为真。

if (v.getChildAt(0).getBottom()==(nestedScroll.getHeight()+nestedScroll.getScrollY()))

这只适用于一段时间......因此,不要以这种方式使用它。

于 2020-10-31T21:20:30.560 回答
0

这对我有用!

            my_scroll_view.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {



                    if (scrollY == v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()) {
                        Log.d(TAG, "onScrollChange: SRCOLLED ==> scrollY: ======================================> THIS IS THE VERY END ");
                    }

                

            }
        });
于 2021-02-10T17:06:27.967 回答
0

Webserve 回答正确,但条件应该是这样的

 if (scrollY == (v?.getChildAt(0)?.measuredHeight ?: 0) - (v?.measuredHeight ?: 0)) {
    //at bottom
    }
于 2020-04-09T10:12:15.223 回答
0

对于 api <23,您可以添加一个 treeObserver.scrollChangeLister 存储一个本地浮点变量并检查您的滚动方式

例子

public class About extends AppCompatActivity implements 
ViewTreeObserver.OnScrollChangedListener{

private float viewScrolled = 0;

   nestedScrollView.getViewTreeObserver().addOnScrollChangedListener(this);

}

@Override
public void onScrollChanged() {

    if (viewScrolled < nestedScrollView.getScrollY()){
        viewScrolled = nestedScrollView.getScrollY();
        Log.d(TAG, "scrolling up");
    }
    if (viewScrolled > nestedScrollView.getScrollY()){
        viewScrolled = nestedScrollView.getScrollY();
        Log.d(TAG, "scrolling down");
    }
}
于 2019-06-14T21:12:46.443 回答