【问题标题】:How to trigger an event when scrollView reach the bottom with Android?当scrollView到达Android底部时如何触发事件?
【发布时间】:2009-08-27 11:38:10
【问题描述】:

我正在寻找一个事件,当用户滚动到底部时,我可以在 scrollView 上使用该事件。

例如,我的项目列表应该自动扩展更多项目。

有什么想法可以做到这一点吗?

感谢您的任何提示。

【问题讨论】:

标签: android events


【解决方案1】:

请阅读这篇文章:Android: Understanding When Scrollview Has Reached The Bottom

源代码:

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) 
{
    // Grab the last child placed in the ScrollView, we need it to determinate the bottom position.
    View view = (View) getChildAt(getChildCount()-1);

    // Calculate the scrolldiff
    int diff = (view.getBottom()-(getHeight()+getScrollY()));

    // if diff is zero, then the bottom has been reached
    if( diff == 0 )
    {
        // notify that we have reached the bottom
        Log.d(ScrollTest.LOG_TAG, "MyScrollView: Bottom has been reached" );
    }

    super.onScrollChanged(l, t, oldl, oldt);
}

如果您愿意,可以添加自定义小部件。

例子:

package se.marteinn.ui;

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


/**
 * Triggers a event when scrolling reaches bottom.
 *
 * Created by martinsandstrom on 2010-05-12.
 * Updated by martinsandstrom on 2014-07-22.
 *
 * Usage:
 *
 *  scrollView.setOnBottomReachedListener(
 *      new InteractiveScrollView.OnBottomReachedListener() {
 *          @Override
 *          public void onBottomReached() {
 *              // do something
 *          }
 *      }
 *  );
 * 
 *
 * Include in layout:
 *  
 *  <se.marteinn.ui.InteractiveScrollView
 *      android:layout_width="match_parent"
 *      android:layout_height="match_parent" />
 *  
 */
public class InteractiveScrollView extends ScrollView {
    OnBottomReachedListener mListener;

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

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

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

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()));

        if (diff == 0 && mListener != null) {
            mListener.onBottomReached();
        }

        super.onScrollChanged(l, t, oldl, oldt);
    }


    // Getters & Setters

    public OnBottomReachedListener getOnBottomReachedListener() {
        return mListener;
    }

    public void setOnBottomReachedListener(
            OnBottomReachedListener onBottomReachedListener) {
        mListener = onBottomReachedListener;
    }


    /**
     * Event listener.
     */
    public interface OnBottomReachedListener{
        public void onBottomReached();
    }

}

【讨论】:

  • 你也可以覆盖 onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) 并检查clampedY是否为真
  • 我很困惑。当你写的时候: int diff = (view.getBottom()-(recyclerView.getHeight()+recyclerView.getScrollY()));为什么我们需要添加recyclerView.getScrollY()? getBottom() 计算总是 w.r.t 父级。为什么我们需要添加偏移量?你能解释一下吗?
【解决方案2】:

我遇到了同样的问题,我通过使用 ListView(如果需要会自动添加 ScrollView)和设置 OnScrollListener 解决了这个问题

这是一个代码示例:

        tableListView.setOnScrollListener(new OnScrollListener() {

        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }

        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            if (visibleItemCount == totalItemCount)
            // too little items (ScrollView not needed)
            {
                java.lang.System.out.println("too little items to use a ScrollView!");
            }
            else {
                if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
                    // put your stuff here
                    java.lang.System.out.println("end of the line reached!");
                }
            }

        }
    });

【讨论】:

    【解决方案3】:

    不要尝试SetOnScrollChangeListener,如果您正在使用低于 21 (android M) 的 android API,您可以试试这个:

    yourScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                @Override
                public void onScrollChanged() {
                    int rootHeight = yourScrollView.getHeight();
                    int childHeight = yourScrollView.getChildAt(0).getHeight();
                    int scrollY = yourScrollView.getScrollY();
                    if(childHeight - rootHeight == scrollY)
                    Log.d("Hei","You Have Reach The End!");
                }
            });
    

    【讨论】:

      【解决方案4】:

      这个答案已经晚了,但如果有人偶然发现,我们可以使用 setOnScrollChangeListener

        childScrollView.setOnScrollChangeListener(object : NestedScrollView.OnScrollChangeListener {
                  override fun onScrollChange(v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int) {
                      when {//maxScrollPixelPoint  is defined local/global variable
                          scrollY > maxScrollPixelPoint -> {
                              maxScrollPixelPoint = scrollY
                          }
                          scrollY == maxScrollPixelPoint -> {
                              //reached bottom 
                          }
                      }
                  }
      
              })
      

      【讨论】:

        【解决方案5】:

        这是一个更简单的解决方案,无需子类化滚动视图。 假设你有一个 RecyclerView recyclerView 变量,

        recyclerView.computeVerticalScrollRange() 为您提供完整的滚动范围,即内容高度。

        (recyclerView.computeVerticalScrollOffset() 在您滚动时给出从顶部的偏移量。该值将持续到内容高度 - 滚动视图高度。

        所以,

            if( (recyclerView.computeVerticalScrollOffset() == 
        (recyclerView.computeVerticalScrollRange() - recyclerView.getHeight()) ) {
            // You have hit rock bottom.
            }
        

        操作滚动视图的子视图看起来很老套。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-21
          • 1970-01-01
          • 2013-04-03
          • 1970-01-01
          • 2018-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多