Android开发拾穗首页投稿(暂停使用,暂停投稿)程序员

ListView未滚动触发onScroll的思考

2016-05-10  本文已影响2206人  a57ecf3aaaf2

发现问题

当我们在处理ListView滚动到底部加载更多时,通常的做法是利用OnScrollListener的onScroll方法,来判断是否滚动到了底部。

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    boolean toBottom = firstVisibleItem + visibleItemCount >= totalItemCount;
    if (toBottom && !isLoading && !isFinish) {
        //...
    }
}

但是这种做法会引发一系列的问题,比如当初始化ListView,并setOnScrollListener时便会回调onScroll方法,此时得到的结果是已经滚动到了底部,在没有任何数据的情况下给出这样一个结果,会对程序的处理逻辑产生影响。

看看源码:

/**
     * Set the listener that will receive notifications every time the list scrolls.
     *
     * @param l the scroll listener
     */
    public void setOnScrollListener(OnScrollListener l) {
        mOnScrollListener = l;
        invokeOnItemScrollListener();
    }

    /**
     * Notify our scroll listener (if there is one) of a change in scroll state
     */
    void invokeOnItemScrollListener() {
        if (mFastScroll != null) {
            mFastScroll.onScroll(mFirstPosition, getChildCount(), mItemCount);
        }
        if (mOnScrollListener != null) {
            mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
        }
        onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
    }

也就是说,在setOnScrollListener时便已经回调了onScroll方法。

解决问题

大多数情况下,大家都忽略了OnScrollListener中的onScrollStateChanged方法。

   public void onScrollStateChanged(AbsListView view, int scrollState);

该方法有两个入参,第二个参数scrollState有三种状态:

    public static int SCROLL_STATE_IDLE = 0;            //结束滚动
    public static int SCROLL_STATE_TOUCH_SCROLL = 1;    //触摸滚动
    public static int SCROLL_STATE_FLING = 2;           //手指离开屏幕后的滚动状态

此时我们可将焦点定位到 SCROLL_STATE_IDLE,将滚动到底部的判断和处理放在结束滚动之后。

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    switch (scrollState) {
        case SCROLL_STATE_IDLE:
            boolean toBottom = view.getLastVisiblePosition() == view.getCount() - 1;
            if (toBottom && !isLoading && !isFinish) {
                //...
            }
            break;
    }

这样便可完美解决onScroll的频繁调用,及首次调用的问题;同时,也成功解决了滚动到底部的逻辑判断和处理。

上一篇下一篇

猜你喜欢

热点阅读