PhotoView icon indicating copy to clipboard operation
PhotoView copied to clipboard

Bad works with viewpager2

Open romakononovich opened this issue 5 years ago • 8 comments

But the problems are that of alpha02 and above ViewPager2, he now final class

romakononovich avatar May 09 '19 13:05 romakononovich

Same here. The inital page is always blank. The photo isn't displayed. THat also happens with the original ImageView, but there, at least, it works when calling notifyDatasetChanged after 1000ms (just a test).

DennyWeinberg avatar May 22 '20 18:05 DennyWeinberg

Also moving the photo when zoomed in doesn't work, since the scroll interception of viewpager2 takes place.

DennyWeinberg avatar May 22 '20 18:05 DennyWeinberg

did you guys solve this problem? need somehow to disable viewpager interactions until image scrolled to the side edge

mykola-dev avatar Jul 02 '20 15:07 mykola-dev

Nope, I'm still using the original vewpager

DennyWeinberg avatar Jul 02 '20 16:07 DennyWeinberg

I have the same problem

sankemao avatar May 12 '21 01:05 sankemao

<---?xml version="1.0" encoding="utf-8"?-->

<---LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:gravity="center">

<com.github.chrisbanes.photoview.PhotoView
    android:id="@+id/pvPhotoView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<--/LinearLayout-->

try this...

PontonMao avatar Feb 14 '22 07:02 PontonMao

A simple fix on incorrect zoom behavior. The problem is at PhotoViewAttacher.java line 101

if (mScaleDragDetector.isScaling()) {
    return; // Do not drag if we are already scaling
}

When user doing multi touch, mScaleDragDetector.isScaling() may return false, and when zoom gesture occurs on edge. line 120 allow parent view to intercept touch event.

if (mAllowParentInterceptOnEdge && !mScaleDragDetector.isScaling() && !mBlockParentIntercept) {
  if (mHorizontalScrollEdge == HORIZONTAL_EDGE_BOTH
          || (mHorizontalScrollEdge == HORIZONTAL_EDGE_LEFT && dx >= 1f)
          || (mHorizontalScrollEdge == HORIZONTAL_EDGE_RIGHT && dx <= -1f)
          || (mVerticalScrollEdge == VERTICAL_EDGE_TOP && dy >= 1f)
          || (mVerticalScrollEdge == VERTICAL_EDGE_BOTTOM && dy <= -1f)) {
      if (parent != null) {
          parent.requestDisallowInterceptTouchEvent(false);
      }
  }
}

FIX (Not changing the original library code) Wrapping PhotoView with a custom PhotoViewWrapper, which redo requestDisallowInterceptTouchEvent after PhotoView wrongly allowing parent view's interception.

PhotoViewWrapper.kt:

class PhotoViewWrapper(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {

    private var isParentInterceptionDisallowed = false

    override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
        isParentInterceptionDisallowed = disallowIntercept
        if (disallowIntercept) {
            // PhotoView wants to disallow parent interception, let it be.
            parent.requestDisallowInterceptTouchEvent(disallowIntercept) // don't ban wrapper itself
        }
        else {
            // PhotoView wants to allow parent interception, we need to re-check it.
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        // always false when up or cancel event,
        // which will allow parent interception normally.
        val isMultiTouch = ev.pointerCount > 1

        // re-check if it's multi touch
        parent.requestDisallowInterceptTouchEvent(
            isParentInterceptionDisallowed || isMultiTouch
        )
        return false
    }
}

layout.xml

<your.view.PhotoViewWrapper
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/black"
        >
      <com.github.chrisbanes.photoview.PhotoView
          android:id="@+id/photoView"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:scaleType="fitCenter"
          />
</your.view.PhotoViewWrapper>

laishere avatar May 04 '22 06:05 laishere

Also can change the source code:

  1. Modify the OnGestureListener.onDrag function, Add isMultiTouch
interface OnGestureListener {

    void onDrag(boolean isMultiTouch, float dx, float dy);
  1. Modify the PhotoViewAttacher at line 126
if (parent != null && !isMultiTouch) {
    parent.requestDisallowInterceptTouchEvent(false);
}
  1. Finally,modify CustomGestureDetector at line 150
mListener.onDrag(ev.getPointerCount() > 1, dx, dy);

qishi604 avatar Sep 27 '23 09:09 qishi604