summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jorim Jaggi <jjaggi@google.com> 2018-12-04 13:38:03 +0100
committer Jorim Jaggi <jjaggi@google.com> 2019-01-08 17:24:17 +0100
commit15637fddc33b958ab3dd41734403ec4c73bf7d9c (patch)
tree467cd18b20010efe96a98589bbd8a5a1f9b895f6
parentbcf99fff7318ae0cb34d7cd973acb5b9b2c64f8a (diff)
A brave new world for window insets (10/n)
Rework how dispatching works for apps targeting Q+ (flagged off at the moment behind VRI.USE_NEW_INSETS) We properly dispatch windows in the hierarchy by fixing the issue that insets modified by onApplyWindowInsets affected all other views later in prefix order, including siblings and siblings of parents. Furthermore, we get rid of stopping dispatch if they are consumed, as it gets a lot more complicated with the granular information we add what consumed actually means. Test: ViewGroupTest, ViewTest Bug: 118118435 Change-Id: I9dfb69ebb93b334bb34d17889282293bec94e1af
-rw-r--r--core/java/android/view/View.java23
-rw-r--r--core/java/android/view/ViewGroup.java16
2 files changed, 39 insertions, 0 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4504887f265b..91677a12338d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -939,6 +939,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private static boolean sAcceptZeroSizeDragShadow;
+ /**
+ * Prior to Q, {@link #dispatchApplyWindowInsets} had some issues:
+ * <ul>
+ * <li>The modified insets changed by {@link #onApplyWindowInsets} were passed to the
+ * entire view hierarchy in prefix order, including siblings as well as siblings of parents
+ * further down the hierarchy. This violates the basic concepts of the view hierarchy, and
+ * thus, the hierarchical dispatching mechanism was hard to use for apps.</li>
+ *
+ * <li>Dispatch was stopped after the insets were fully consumed. This is somewhat confusing
+ * for developers, but more importantly, by adding more granular information to
+ * {@link WindowInsets} it becomes really cumbersome to define what consumed actually means
+ * </li>
+ * </ul>
+ *
+ * In order to make window inset dispatching work properly, we dispatch window insets
+ * in the view hierarchy in a proper hierarchical manner and don't stop dispatching if the
+ * insets are consumed if this flag is set to {@code false}.
+ */
+ static boolean sBrokenInsetsDispatch;
+
/** @hide */
@IntDef({NOT_FOCUSABLE, FOCUSABLE, FOCUSABLE_AUTO})
@Retention(RetentionPolicy.SOURCE)
@@ -5108,6 +5128,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
sAcceptZeroSizeDragShadow = targetSdkVersion < Build.VERSION_CODES.P;
+ sBrokenInsetsDispatch = !ViewRootImpl.USE_NEW_INSETS
+ || targetSdkVersion < Build.VERSION_CODES.Q;
+
sCompatibilityDone = true;
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8372032593b0..9d11397498cf 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7111,6 +7111,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
insets = super.dispatchApplyWindowInsets(insets);
+ if (View.sBrokenInsetsDispatch) {
+ return brokenDispatchApplyWindowInsets(insets);
+ } else {
+ return newDispatchApplyWindowInsets(insets);
+ }
+ }
+
+ private WindowInsets brokenDispatchApplyWindowInsets(WindowInsets insets) {
if (!insets.isConsumed()) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
@@ -7123,6 +7131,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return insets;
}
+ private WindowInsets newDispatchApplyWindowInsets(WindowInsets insets) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ getChildAt(i).dispatchApplyWindowInsets(insets);
+ }
+ return insets;
+ }
+
/**
* Returns the animation listener to which layout animation events are
* sent.