Make sure touch only goes to the nearest button when it makes sense

- In NearestTouchFrame, we can't use view bounds alone since the buttons do not have the same root (3 buttons are in the main container, while the contextual buttons are in the contextual button container). This currently caused the issue that contextual button region, when the contextual buttons are invisible, triggers overview
- Need to add an empty space in the left / top area of the button nav to prevent view clicks from going into back (that's how it works in navigationbar/)

Bug: 25768138
Test: left and right of 3 buttons don't trigger back or overview
Change-Id: Idc26c0c8ac0ecc000300a6db2e3e6251f678dada
This commit is contained in:
Tracy Zhou
2024-01-30 11:16:13 -08:00
parent ea9522eee5
commit 419140aede
14 changed files with 101 additions and 29 deletions
@@ -27,6 +27,7 @@ import android.widget.FrameLayout;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -42,7 +43,10 @@ public class NearestTouchFrame extends FrameLayout {
private final List<View> mClickableChildren = new ArrayList<>();
private final List<View> mAttachedChildren = new ArrayList<>();
private final boolean mIsActive;
private final int[] mTmpInt = new int[2];
// Offset (as the base) to translate window cords to view cords.
private final int[] mWindowOffset = new int[2];
private boolean mIsVertical;
private View mTouchingChild;
private final Map<View, Rect> mTouchableRegions = new HashMap<>();
@@ -52,8 +56,11 @@ public class NearestTouchFrame extends FrameLayout {
*/
private final Comparator<View> mChildRegionComparator =
(view1, view2) -> {
int startingCoordView1 = mIsVertical ? view1.getTop() : view1.getLeft();
int startingCoordView2 = mIsVertical ? view2.getTop() : view2.getLeft();
int leftTopIndex = mIsVertical ? 1 : 0;
view1.getLocationInWindow(mTmpInt);
int startingCoordView1 = mTmpInt[leftTopIndex] - mWindowOffset[leftTopIndex];
view2.getLocationInWindow(mTmpInt);
int startingCoordView2 = mTmpInt[leftTopIndex] - mWindowOffset[leftTopIndex];
return startingCoordView1 - startingCoordView2;
};
@@ -74,6 +81,7 @@ public class NearestTouchFrame extends FrameLayout {
mAttachedChildren.clear();
mTouchableRegions.clear();
addClickableChildren(this);
getLocationInWindow(mWindowOffset);
cacheClosestChildLocations();
}
@@ -147,8 +155,9 @@ public class NearestTouchFrame extends FrameLayout {
}
private Rect getChildsBounds(View child) {
int left = child.getLeft();
int top = child.getTop();
child.getLocationInWindow(mTmpInt);
int left = mTmpInt[0] - mWindowOffset[0];
int top = mTmpInt[1] - mWindowOffset[1];
int right = left + child.getWidth();
int bottom = top + child.getHeight();
return new Rect(left, top, right, bottom);
@@ -194,6 +203,7 @@ public class NearestTouchFrame extends FrameLayout {
public void dumpLogs(String prefix, PrintWriter pw) {
pw.println(prefix + "NearestTouchFrame:");
pw.println(String.format("%s\tmWindowOffset=%s", prefix, Arrays.toString(mWindowOffset)));
pw.println(String.format("%s\tmIsVertical=%s", prefix, mIsVertical));
pw.println(String.format("%s\tmTouchingChild=%s", prefix, mTouchingChild));
pw.println(String.format("%s\tmTouchableRegions=%s", prefix,