boycy815 / PinchImageView

体验极佳的Android图片手势控件。An Android image gesture control with excellent user experience.
MIT License
1.96k stars 495 forks source link

不支持使用PagerSnapHelper的recyclerView #45

Closed LongAgoLong closed 2 months ago

LongAgoLong commented 6 years ago

使用PagerSnapHelper的recyclerView可以替代viewpager,但是控件在recyclerView中缩放事件无法触发

1970633640 commented 6 years ago

是只要一滑动recyclerview就滑动,无论图片缩放如何,同问

Bgtal commented 5 years ago

是只要一滑动recyclerview就滑动,无论图片缩放如何,同问

我的解决方案就是1.在PinchImageView 里面的添加一个boolean 参数控制是否需要放弃touch方法。


    private boolean isInTouch = false;

    public boolean isInTouchAction() {
        return isInTouch;
    }
    public boolean onTouchEvent(MotionEvent event) {
        ....
       if (action == MotionEvent.ACTION_DOWN) {
            //在矩阵动画过程中不允许启动滚动模式
            if (!(mScaleAnimator != null && mScaleAnimator.isRunning())) {
                    isInTouch = true;
            }
       }
       ....
    }

    private boolean scrollBy(float xDiff, float yDiff) {
        if (!isReady()) {
            SnbLog.e(">>>>>sssdf:false");
            return false;
        }
        //原图方框
        RectF bound = MathUtils.rectFTake();
        getImageBound(bound);
        //控件大小
        float displayWidth = getWidth();
        float displayHeight = getHeight();
        //如果当前图片宽度小于控件宽度,则不能移动
        if (bound.right - bound.left < displayWidth) {
            xDiff = 0;
            //如果图片左边在移动后超出控件左边
            isInTouch = false;
        } else if (bound.left + xDiff > 0) {
            //如果在移动之前是没超出的,计算应该移动的距离
            if (bound.left < 0) {
                xDiff = -bound.left;
                //否则无法移动
                isInTouch = true;
            } else {
                xDiff = 0;
                isInTouch = false;
            }
            //如果图片右边在移动后超出控件右边
        } else if (bound.right + xDiff < displayWidth) {
            //如果在移动之前是没超出的,计算应该移动的距离
            if (bound.right > displayWidth) {
                xDiff = displayWidth - bound.right;
                isInTouch = true;
                //否则无法移动
            } else {
                xDiff = 0;
                isInTouch = false;
            }
        }
        //以下同理
        if (bound.bottom - bound.top < displayHeight) {
            yDiff = 0;
        } else if (bound.top + yDiff > 0) {
            if (bound.top < 0) {
                yDiff = -bound.top;
            } else {
                yDiff = 0;
            }
        } else if (bound.bottom + yDiff < displayHeight) {
            if (bound.bottom > displayHeight) {
                yDiff = displayHeight - bound.bottom;
            } else {
                yDiff = 0;
            }
        }
       ....
    }

private void scaleEnd(){
//启动矩阵动画
            mScaleAnimator = new ScaleAnimator(mOuterMatrix, animEnd);
            mScaleAnimator.addListener(new Animator.AnimatorListener() {
               ,,,
                @Override
                public void onAnimationEnd(Animator animation) {
                    isInTouch = false;
                }
                ....
            });

}

2.在用到的LayoutManager 重写canScrollHorizontally()或canScrollVertically() 来控制recyclerview 能不能滑

 LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false) {
            @Override
            public boolean canScrollHorizontally() {
                if (currentImageView != null) {
                    return !currentImageView.isInTouchAction();
                }
                return true;
            }
        };

上面的scrollBy只判断的左右的超出了之后的事情,如果recyclerview是上下滑需要把判断放大y方向上。 目前是这样解决的,双指的时候可能还有点问题,基本使用问题不大。

1970633640 commented 5 years ago

我也不知道怎么引用回复,就直接发了。貌似这个库只是手势,并没有分块加载功能,作者的demo是手动实现的分块加载。貌似比较成熟的库还是ssiv