diff options
author | 2021-08-19 13:54:06 +0800 | |
---|---|---|
committer | 2021-08-20 10:21:21 +0800 | |
commit | e15fa709e608fa46bd3f99c2185d90ecc068ec5d (patch) | |
tree | c793365e6d102a626e0b8dfaf7b35f341e9ba1c7 | |
parent | bc3cf7bfc16909fddff3f930eb03834013245df6 (diff) |
Fix preview icon tapping behavior when magnifying the screen
We user the unscaled coordinate to determine whether the event is
in the bounds of the view. It doesn't work in magnification scenario
because the view size is not changed and getRawX()/getRawY() is the actual
position on the screen.
To fix it, we determine it in the parent's coordinate. In our case
the event is dispatched from RecyclerView, so the calculation is in
Recyclerview's coordinate
Bug: 152265995
Test: manual test
Change-Id: If6e2497641d16b92542f3fc6576929c52fe48fbb
5 files changed, 36 insertions, 11 deletions
diff --git a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java index 930773bd3..0357f1277 100644 --- a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java +++ b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java @@ -81,7 +81,8 @@ final class GridDirectoryHolder extends DocumentHolder { @Override public boolean inSelectRegion(MotionEvent event) { - return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, mIconLayout) : false; + return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, itemView.getParent(), + mIconLayout) : false; } /** diff --git a/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/src/com/android/documentsui/dirlist/GridDocumentHolder.java index 631298f12..1a3e24ea4 100644 --- a/src/com/android/documentsui/dirlist/GridDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/GridDocumentHolder.java @@ -137,12 +137,12 @@ final class GridDocumentHolder extends DocumentHolder { @Override public boolean inSelectRegion(MotionEvent event) { - return Views.isEventOver(event, mIconLayout); + return Views.isEventOver(event, itemView.getParent(), mIconLayout); } @Override public boolean inPreviewIconRegion(MotionEvent event) { - return Views.isEventOver(event, mPreviewIcon); + return Views.isEventOver(event, itemView.getParent(), mPreviewIcon); } /** diff --git a/src/com/android/documentsui/dirlist/GridPhotoHolder.java b/src/com/android/documentsui/dirlist/GridPhotoHolder.java index b415ebac3..2b5e5e2f8 100644 --- a/src/com/android/documentsui/dirlist/GridPhotoHolder.java +++ b/src/com/android/documentsui/dirlist/GridPhotoHolder.java @@ -125,7 +125,7 @@ final class GridPhotoHolder extends DocumentHolder { @Override public boolean inPreviewIconRegion(MotionEvent event) { - return Views.isEventOver(event, mPreviewIcon); + return Views.isEventOver(event, itemView.getParent(), mPreviewIcon); } /** diff --git a/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/src/com/android/documentsui/dirlist/ListDocumentHolder.java index f6a900236..984900699 100644 --- a/src/com/android/documentsui/dirlist/ListDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/ListDocumentHolder.java @@ -180,12 +180,12 @@ final class ListDocumentHolder extends DocumentHolder { @Override public boolean inSelectRegion(MotionEvent event) { return (mDoc.isDirectory() && !(mAction == State.ACTION_BROWSE)) ? - false : Views.isEventOver(event, mIconLayout); + false : Views.isEventOver(event, itemView.getParent(), mIconLayout); } @Override public boolean inPreviewIconRegion(MotionEvent event) { - return Views.isEventOver(event, mPreviewIcon); + return Views.isEventOver(event, itemView.getParent(), mPreviewIcon); } /** diff --git a/src/com/android/documentsui/ui/Views.java b/src/com/android/documentsui/ui/Views.java index 2ac27b284..cebd0ccf0 100644 --- a/src/com/android/documentsui/ui/Views.java +++ b/src/com/android/documentsui/ui/Views.java @@ -19,6 +19,8 @@ package com.android.documentsui.ui; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; /** * A utility class for working with Views. @@ -28,22 +30,44 @@ public final class Views { private Views() {} /** - * Return whether the event is in the view's region + * + * Return whether the event is in the view's region. We determine it with in the coordinate + * of the parent view that dispatches the motion event. * @param event the motion event + * @param eventSource the view dispatching the motion events. * @param view the view to check the selection region * @return True, if the event is in the region. Otherwise, return false. */ - public static boolean isEventOver(MotionEvent event, View view) { + + public static boolean isEventOver(MotionEvent event, ViewParent eventSource, View view) { if (view == null || event == null || !view.isAttachedToWindow()) { return false; } + View parent = null; + if (eventSource instanceof ViewGroup) { + parent = (View) eventSource; + } + + final Rect viewBoundsOnGlobalCoordinate = getBoundsOnScreen(view); + + // If the parent is null, it means view is the view root of the window, so the event + // should be from view itself, in this case we don't need any offset. + final int[] viewParentCoord = new int[2]; + if (parent != null) { + parent.getLocationOnScreen(viewParentCoord); + } + + Rect viewBoundsOnParentViewCoordinate = new Rect(viewBoundsOnGlobalCoordinate); + viewBoundsOnParentViewCoordinate.offset(-viewParentCoord[0], -viewParentCoord[1]); + return viewBoundsOnParentViewCoordinate.contains((int) event.getX(), (int) event.getY()); + } + + private static Rect getBoundsOnScreen(View view) { final int[] coord = new int[2]; view.getLocationOnScreen(coord); - final Rect viewRect = new Rect(coord[0], coord[1], coord[0] + view.getMeasuredWidth(), + return new Rect(coord[0], coord[1], coord[0] + view.getMeasuredWidth(), coord[1] + view.getMeasuredHeight()); - - return viewRect.contains((int) event.getRawX(), (int) event.getRawY()); } } |