现在的位置: 首页 > 综合 > 正文

ListView滚动事件响应,监听滚动到表头、表尾

2018年01月18日 ⁄ 综合 ⁄ 共 2136字 ⁄ 字号 评论关闭

ListView滚动事件响应

ListView本身有一个OnScrollListener的接口,通过此接口可以监听列表的状态,滚动的个数,但是没法监听其精确的
滚动距离,上下滚动事件和滚动到表头或表尾事件,下面介绍如何对这些事件做响应。

1. 上下滚动事件的响应

1. 自定义一个继承至ListView的类。
2. 覆写onTouchEvent方法,监听触摸事件。
3. 定义一个有效滚动距离,当滑动的距离超过这个距离时才会触发滚动事件的响应。


    private int mEffectiveDistance = 10;
    private float mPreviousY;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        mDetector.onTouchEvent(ev);
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float currentY = ev.getY();
                float distanceY = currentY - mPreviousY;
                if (distanceY < -mEffectiveDistance) {
                    mPreviousY = currentY;
                    if (mCallbacks != null) {
                        mCallbacks.onScrollUp();  //触发向上滚动的事件
                    }
                } else if (distanceY > mEffectiveDistance) {
                    mPreviousY = currentY;
                    if (mCallbacks != null) {
                        mCallbacks.onScrollDown();  //触发向下滚动的事件
                    }
                }
                break;

            case MotionEvent.ACTION_DOWN:
                mPreviousY = ev.getY();
                break;

            default:
                break;

        }
        return super.onTouchEvent(ev);
    }

Edit

2. 滚动到表头或表尾事件的响应

1. 自定义的ListView类要实现AbsListView.OnScrollListener接口。
2. 覆写onScrollStateChanged(AbsListView view, int scrollState)方法,监听列表的滚动事件,
其中view就是当前ListView,scrollState表示当前ListView的状态,它有三个状态:
SCROLL_STATE_IDLE(停止滚动的空闲状态)、
SCROLL_STATE_TOUCH_SCROLL(手指有接触屏幕并且带动ListView滚动的状态)、
SCROLL_STATE_FLING(手指离开的屏幕,ListView因为惯性还在滚动的状态)。
3. 当当前ListView状态是SCROLL_STATE_IDLE时进行事件监听。

滚动到表头的事件

  • 当列表中的第一个子View的顶部Y坐标等于列表顶部Y坐标时响应
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
            View firstChild = view.getChildAt(0);
            if (view.getTop() == firstChild.getTop()) {
                if (mCallbacks != null) {
                    mCallbacks.onScrollFirst();   //触发滚动到表头的事件
                }
            }
        }
    }

滚动到表尾的事件

  • 当列表中的最后一个子View的底部Y坐标等于列表底部Y坐标时响应
  • 如果整个列表的长度比父View小,那么当最后一个子View的底部Y坐标等于列表的长度时响应
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        int count = getCount();
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
                && getLastVisiblePosition() == count - 1) {
            View lastChild = view.getChildAt(view.getChildCount() - 1);
            int dist = view.getBottom() - lastChild.getBottom();
            if (dist == 0) {
                if (mCallbacks != null) {
                    mCallbacks.onScrollLast();   //触发滚动到表尾的事件
                }
            }
            if (count < MIN_CHILD_COUNT) {   //设置一个最小个数,提高效率
                int childViewsHeight = (lastChild.getHeight()
                        + getDividerHeight()) * count;
                if (childViewsHeight < view.getHeight() && childViewsHeight == lastChild.getBottom()) {
                    if (mCallbacks != null) {
                        mCallbacks.onScrollLast();   //触发滚动到表尾的事件
                    }
                }
            }
        }
    }

抱歉!评论已关闭.