Photoview: Will support RecyclerView + PagerSnapHelper

Created on 14 Sep 2018  ·  7Comments  ·  Source: Baseflow/PhotoView

Most helpful comment

I fix it ,you only need override RecyclerView .
@imyyq-star

public class RecyclerViewViewPager extends RecyclerView {

private ScaleGestureDetector gestureDetector;

/**
 * 标记位  isScaleing 是否正在缩放,hasMorePointers 是否多个手指在屏幕上
 */
private boolean isScaleing,hasMorePointers;

public RecyclerViewViewPager(Context context) {
    super(context);
    init(context);
}

public RecyclerViewViewPager(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public RecyclerViewViewPager(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
    gestureDetector = new ScaleGestureDetector(context,new GestureListener());
}

class GestureListener implements ScaleGestureDetector.OnScaleGestureListener{

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        isScaleing = true;
        return false;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return false;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        isScaleing = false;
    }
}


@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    gestureDetector.onTouchEvent(ev);
    if (ev.getPointerCount() > 1) {
        hasMorePointers = true;
    }else {
        hasMorePointers= false;
    }
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    if (isScaleing || hasMorePointers){
        return false;
    }
    return super.onInterceptTouchEvent(e);
}

}

All 7 comments

Works for me.

Works for me.

RecyclerView + PagerSnapHelper can be scaled, but not smooth enough, often slides to the next page

I have a need to add and remove children for the image list.
However, the addition and deletion of ViewPager is too unfriendly.

RecyclerView + PagerSnapHelper can be scaled, but not smooth enough, often slides to the next page
I have the same question ,Have you solved it? @imyyq-star

I fix it ,you only need override RecyclerView .
@imyyq-star

public class RecyclerViewViewPager extends RecyclerView {

private ScaleGestureDetector gestureDetector;

/**
 * 标记位  isScaleing 是否正在缩放,hasMorePointers 是否多个手指在屏幕上
 */
private boolean isScaleing,hasMorePointers;

public RecyclerViewViewPager(Context context) {
    super(context);
    init(context);
}

public RecyclerViewViewPager(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public RecyclerViewViewPager(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
    gestureDetector = new ScaleGestureDetector(context,new GestureListener());
}

class GestureListener implements ScaleGestureDetector.OnScaleGestureListener{

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        isScaleing = true;
        return false;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return false;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        isScaleing = false;
    }
}


@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    gestureDetector.onTouchEvent(ev);
    if (ev.getPointerCount() > 1) {
        hasMorePointers = true;
    }else {
        hasMorePointers= false;
    }
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    if (isScaleing || hasMorePointers){
        return false;
    }
    return super.onInterceptTouchEvent(e);
}

}

@walkingCoder

还是不完美,你试一下一开始双指缩放,然后松开一个手指,很容易又滑到下一张了

@imyyq-star

I have just solved a similar problem recently and provided an idea that I hope will help you.
In the OnGestureListener of PhotoViewAttacher, increase the judgment of the sliding angle as follows:

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)) {
                    //add the line below
                    if (Math.abs(dx) >= 10f && Math.abs(dx) > Math.abs(dy)) {
                        if (parent != null) {
                            parent.requestDisallowInterceptTouchEvent(false);
                        }
                    }
                }

The idea is to judge the instantaneous coordinate changes in the move process. If the page is complex, you can override the dispatchTouchEvent in your custom Recyclerview. At present, the effect on my side is quite good. It also supports the smooth sliding of the large image(match_parent of Width and wrap_content of Height) with more than one screen.

Was this page helpful?
0 / 5 - 0 ratings