Skip to content

Commit

Permalink
fix: Allow parents view to intercept or not touch depending on the ri…
Browse files Browse the repository at this point in the history
…ght conditions
  • Loading branch information
tevincent committed Mar 5, 2025
1 parent 65e9af2 commit a96567f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ public void startPageFlingAnimation(float targetOffset) {

void computeFling() {
if (scroller.computeScrollOffset()) {
pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY());
pdfView.loadPageByOffset();
if (shouldHandleScrollerValue()) {
pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY());
pdfView.loadPageByOffset();
}
} else if (flinging) { // fling finished
flinging = false;
pdfView.loadPages();
Expand All @@ -116,6 +118,16 @@ void computeFling() {
}
}

private boolean shouldHandleScrollerValue() {
// Sometimes, when we reach the end of the PDF and we perform a scroll, the scroller sometimes return 0 when we
// release the touch.
if (pdfView.isSwipeVertical()) {
return scroller.getCurrY() != 0 && scroller.getCurrY() != pdfView.getDocumentLength();
} else {
return scroller.getCurrX() != 0;
}
}

public void stopAll() {
if (animation != null) {
animation.cancel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,12 @@ private boolean shouldOverrideTouchPriority(View v, MotionEvent event) {
(!canScrollRight && scrollDirection == DIRECTION_SCROLLING_LEFT)
|| (!canScrollLeft && scrollDirection == DIRECTION_SCROLLING_RIGHT);

if (event.getAction() == MotionEvent.ACTION_MOVE && canScrollHorizontally) {
startingTouchXPosition = STARTING_TOUCH_POSITION_NOT_INITIALIZED;
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (canScrollHorizontally) {
startingTouchXPosition = STARTING_TOUCH_POSITION_NOT_INITIALIZED;
} else if (startingTouchXPosition == STARTING_TOUCH_POSITION_NOT_INITIALIZED) {
startingTouchXPosition = event.getX();
}
}

if (!isScrollingBlocked || startingTouchXPosition == STARTING_TOUCH_POSITION_NOT_INITIALIZED) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public void jumpTo(int page, boolean withAnimation) {
}

page = pdfFile.determineValidPageNumberFrom(page);
float offset = -pdfFile.getPageOffset(page, zoom) + pageSeparatorSpacing;
float offset = -pdfFile.getPageOffset(page, zoom) + pageSeparatorSpacing + startSpacing;
if (swipeVertical) {
if (withAnimation) {
animationManager.startYAnimation(currentYOffset, offset);
Expand Down Expand Up @@ -719,14 +719,11 @@ protected void onDraw(Canvas canvas) {
}

// Moves the canvas before drawing any element
float currentXOffset = this.currentXOffset;
float currentYOffset = this.currentYOffset;
canvas.translate(currentXOffset, currentYOffset);

// Draws thumbnails
for (PagePart part : cacheManager.getThumbnails()) {
drawPart(canvas, part);

}

// Draws parts
Expand Down Expand Up @@ -970,11 +967,11 @@ public void moveTo(float offsetX, float offsetY, boolean moveHandle) {
if (contentHeight < getHeight()) { // whole document height visible on screen
offsetY = (getHeight() - contentHeight) / 2;
} else {
float maxOffsetY = toCurrentScale((verticalBorder * 2f) - startSpacing);
float maxOffsetY = toCurrentScale((verticalBorder * 2f) + startSpacing);
if (offsetY > maxOffsetY) { // top visible
offsetY = maxOffsetY;
} else if (offsetY + contentHeight + toCurrentScale((verticalBorder * 2f)) < getHeight() + toCurrentScale(endSpacing)) { // bottom visible
offsetY = -contentHeight + getHeight() + toCurrentScale(endSpacing - (verticalBorder * 2f));
} else if (offsetY < getMinOffsetY()) { // bottom visible
offsetY = getMinOffsetY();
}
}

Expand Down Expand Up @@ -1006,7 +1003,7 @@ public void moveTo(float offsetX, float offsetY, boolean moveHandle) {
float maxOffsetX = toCurrentScale((horizontalBorder * 2f) - startSpacing);
if (offsetX > maxOffsetX) { // left visible
offsetX = maxOffsetX;
} else if (offsetX + contentWidth + toCurrentScale((horizontalBorder * 2f)) < getWidth() + toCurrentScale(endSpacing)) { // right visible
} else if (offsetX + contentWidth + toCurrentScale((horizontalBorder * 2f)) < getWidth() + toCurrentScale(endSpacing)) { // right visible
offsetX = -contentWidth + getWidth() + toCurrentScale(endSpacing - (horizontalBorder * 2f));
}
}
Expand Down Expand Up @@ -1056,6 +1053,14 @@ void loadPageByOffset() {
}
}

private float getMinOffsetY() {
return getHeight() - toCurrentScale(endSpacing) - toCurrentScale(verticalBorder * 2f) - pdfFile.getDocLen(zoom);
}

public int getDocumentLength() {
return (int) (getHeight() - pdfFile.getDocLen(zoom));
}

/**
* Animate to the nearest snapping position for the current SnapPolicy
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import android.view.ViewParent;

import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.infomaniak.lib.pdfview.PDFView;

public class TouchUtils {

Expand All @@ -17,11 +20,13 @@ private TouchUtils() {
throw new IllegalStateException("Utility class");
}

public static void handleTouchPriority(MotionEvent event,
View view,
int pointerCount,
boolean shouldOverrideTouchPriority,
boolean isZooming) {
public static void handleTouchPriority(
MotionEvent event,
View view,
int pointerCount,
boolean shouldOverrideTouchPriority,
boolean isZooming
) {
ViewParent viewToDisableTouch = getViewToDisableTouch(view);

if (viewToDisableTouch == null) {
Expand All @@ -34,6 +39,11 @@ public static void handleTouchPriority(MotionEvent event,
view.canScrollVertically(DIRECTION_SCROLLING_TOP) && view.canScrollVertically(DIRECTION_SCROLLING_BOTTOM);
if (shouldOverrideTouchPriority) {
viewToDisableTouch.requestDisallowInterceptTouchEvent(false);

ViewParent viewPager = getViewPager(view);
if (viewPager != null) {
viewPager.requestDisallowInterceptTouchEvent(true);
}
} else if (event.getPointerCount() >= pointerCount || canScrollHorizontally || canScrollVertically) {
int action = event.getAction();

Expand All @@ -47,9 +57,21 @@ public static void handleTouchPriority(MotionEvent event,

private static ViewParent getViewToDisableTouch(View startingView) {
ViewParent parentView = startingView.getParent();

while (parentView != null && !(parentView instanceof RecyclerView)) {
parentView = parentView.getParent();
}

return parentView;
}

private static ViewParent getViewPager(View startingView) {
ViewParent parentView = startingView.getParent();

while (parentView != null && !(parentView instanceof ViewPager2)) {
parentView = parentView.getParent();
}

return parentView;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class PDFViewActivity : AppCompatActivity(), OnPageChangeListener, OnLoadComplet
private const val HANDLE_PADDING_BOTTOM_DP = 40
private const val PDF_PAGE_SPACING_DP = 10
private const val DEFAULT_TEXT_SIZE_DP = 16
private const val START_END_SPACING_DP = 200
private const val START_END_SPACING_DP = 10
private const val MIN_ZOOM = 0.93f
private const val MID_ZOOM = 3.0f
private const val MAX_ZOOM = 6.0f
Expand Down

0 comments on commit a96567f

Please sign in to comment.