diff options
| author | 2018-12-04 13:38:03 +0100 | |
|---|---|---|
| committer | 2019-01-08 17:24:17 +0100 | |
| commit | 15637fddc33b958ab3dd41734403ec4c73bf7d9c (patch) | |
| tree | 467cd18b20010efe96a98589bbd8a5a1f9b895f6 | |
| parent | bcf99fff7318ae0cb34d7cd973acb5b9b2c64f8a (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.java | 23 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 16 |
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. |