解决 PulltoRefreshListView 使用 setSelection 后的滑动卡顿问题

PullToRefreshListview 下拉刷新控件本身有一个问题,就是当使用 setSelection 后,第一次滑动会卡住,后面再次滑动就没有问题了。而需求就是,我们需要在 PullToRefreshListview 上浮动一个菜单,滑倒顶部的时候,header 里面的菜单显示,浮动的菜单隐藏,等上拉至 header 里面的菜单隐藏后,浮动的菜单就显示出来。

因为第一次滑动会卡顿,所以我们可以用代码模拟一个细微的肉眼无法察觉的滑动,这样我们再次滑动的时候就没有问题,核心代码如下:

if(mFloatingFilterView.getVisibility() == View.VISIBLE) {
            ptrlv.getRefreshableView().setSelection(1);
//            ptrlv.getRefreshableView().smoothScrollToPosition(1);
            UIUtil.postDelayed(new Runnable() {
                @Override
                public void run() {
                    CommonUtil.analogUserScroll(ptrlv, 0x01, ScreenUtil.getDeviceWidth() / 2, ScreenUtil.getDeviceHeight() / 2, ScreenUtil.getDeviceWidth() / 2, ScreenUtil.getDeviceHeight());
                }
            }, 100);

        }
/**
     * 模拟用户滑动操作
     *
     * @param view 要触发操作的view
     * @param type 模拟操作类型:均匀滑动、快速滑动
     * @param p1x  滑动的起始点x坐标
     * @param p1y  滑动的起始点y坐标
     * @param p2x  滑动的终点x坐标
     * @param p2y  滑动的终点y坐标
     */
    public static void analogUserScroll(View view, final int type, final float p1x, final float p1y, final float p2x, final float p2y) {
        if (view == null) {
            return;
        }
        long downTime = SystemClock.uptimeMillis();//模拟按下去的时间

        long eventTime = downTime;

        float pX = p1x;
        float pY = p1y;
        int speed = 0;//快速滑动
        float touchTime = 116;//模拟滑动时发生的触摸事件次数

        //平均每次事件要移动的距离
        float perX = (p2x - p1x) / touchTime;
        float perY = (p2y - p1y) / touchTime;

        boolean isReversal = perX < 0 || perY < 0;//判断是否反向:手指从下往上滑动,或者手指从右往左滑动
        boolean isHandY = Math.abs(perY) > Math.abs(perX);//判断是左右滑动还是上下滑动

        if (type == USER_TOUCH_TYPE_1) {//加速滑动
            touchTime = 10;//如果是快速滑动,则发生的触摸事件比均匀滑动更少
            speed = isReversal ? -20 : 20;//反向移动则坐标每次递减
        }

        //模拟用户按下
        MotionEvent downEvent = MotionEvent.obtain(downTime, eventTime,
                ACTION_DOWN, pX, pY, 0);
        view.dispatchTouchEvent(downEvent);

        //模拟移动过程中的事件
        List moveEvents = new ArrayList<>();
        boolean isSkip = false;
        for (int i = 0; i < touchTime; i++) {

            pX += (perX + speed);
            pY += (perY + speed);
            if ((isReversal && pX < p2x) || (!isReversal && pX > p2x)) {
                pX = p2x;
                isSkip = !isHandY;
            }

            if ((isReversal && pY < p2y) || (!isReversal && pY > p2y)) {
                pY = p2y;
                isSkip = isHandY;
            }
            eventTime += 20.0f;//事件发生的时间要不断递增
            MotionEvent moveEvent = getMoveEvent(downTime, eventTime, pX, pY);
            moveEvents.add(moveEvent);
            view.dispatchTouchEvent(moveEvent);
            if (type == USER_TOUCH_TYPE_1) {//加速滑动
                speed += (isReversal ? -70 : 70);
            }
            if (isSkip) {
                break;
            }
        }

        //模拟手指离开屏幕
        MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_UP, pX, pY, 0);
        view.dispatchTouchEvent(upEvent);

        //回收触摸事件
        downEvent.recycle();
        for (int i = 0; i < moveEvents.size(); i++) {
            moveEvents.get(i).recycle();
        }
        upEvent.recycle();
    }

    private static MotionEvent getMoveEvent(long downTime, long eventTime, float pX, float pY) {
        return MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, pX, pY, 0);
    }

你可能感兴趣的:(解决 PulltoRefreshListView 使用 setSelection 后的滑动卡顿问题)