diff options
Diffstat (limited to 'core/java/android/view/View.java')
| -rw-r--r-- | core/java/android/view/View.java | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 8d69477..e6debc1 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2269,6 +2269,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, static final int PFLAG3_CALLED_SUPER = 0x10; + /** + * Flag indicating that we're in the process of applying window insets. + */ + static final int PFLAG3_APPLYING_INSETS = 0x40; + + /** + * Flag indicating that we're in the process of fitting system windows using the old method. + */ + static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80; + /* End of masks for mPrivateFlags3 */ static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED; @@ -3178,6 +3188,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private OnDragListener mOnDragListener; private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener; + + OnApplyWindowInsetsListener mOnApplyWindowInsetsListener; } ListenerInfo mListenerInfo; @@ -5903,8 +5915,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #getFitsSystemWindows() * @see #setFitsSystemWindows(boolean) * @see #setSystemUiVisibility(int) + * + * @deprecated As of API XX use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply + * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use + * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)} + * to implement handling their own insets. */ protected boolean fitSystemWindows(Rect insets) { + if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) { + // If we're not in the process of dispatching the newer apply insets call, + // that means we're not in the compatibility path. Dispatch into the newer + // apply insets path and take things from there. + try { + mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS; + return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets(); + } finally { + mPrivateFlags3 &= PFLAG3_FITTING_SYSTEM_WINDOWS; + } + } else { + // We're being called from the newer apply insets path. + // Perform the standard fallback behavior. + return fitSystemWindowsInt(insets); + } + } + + private boolean fitSystemWindowsInt(Rect insets) { if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) { mUserPaddingStart = UNDEFINED_PADDING; mUserPaddingEnd = UNDEFINED_PADDING; @@ -5924,6 +5959,97 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Called when the view should apply {@link WindowInsets} according to its internal policy. + * + * <p>This method should be overridden by views that wish to apply a policy different from or + * in addition to the default behavior. Clients that wish to force a view subtree + * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p> + * + * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set + * it will be called during dispatch instead of this method. The listener may optionally + * call this method from its own implementation if it wishes to apply the view's default + * insets policy in addition to its own.</p> + * + * <p>Implementations of this method should either return the insets parameter unchanged + * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed + * that this view applied itself. This allows new inset types added in future platform + * versions to pass through existing implementations unchanged without being erroneously + * consumed.</p> + * + * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows} + * property is set then the view will consume the system window insets and apply them + * as padding for the view.</p> + * + * @param insets Insets to apply + * @return The supplied insets with any applied insets consumed + */ + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) { + // We weren't called from within a direct call to fitSystemWindows, + // call into it as a fallback in case we're in a class that overrides it + // and has logic to perform. + if (fitSystemWindows(insets.getSystemWindowInsets())) { + return insets.cloneWithSystemWindowInsetsConsumed(); + } + } else { + // We were called from within a direct call to fitSystemWindows. + if (fitSystemWindowsInt(insets.getSystemWindowInsets())) { + return insets.cloneWithSystemWindowInsetsConsumed(); + } + } + return insets; + } + + /** + * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying + * window insets to this view. The listener's + * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets} + * method will be called instead of the view's + * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. + * + * @param listener Listener to set + * + * @see #onApplyWindowInsets(WindowInsets) + */ + public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) { + getListenerInfo().mOnApplyWindowInsetsListener = listener; + } + + /** + * Request to apply the given window insets to this view or another view in its subtree. + * + * <p>This method should be called by clients wishing to apply insets corresponding to areas + * obscured by window decorations or overlays. This can include the status and navigation bars, + * action bars, input methods and more. New inset categories may be added in the future. + * The method returns the insets provided minus any that were applied by this view or its + * children.</p> + * + * <p>Clients wishing to provide custom behavior should override the + * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a + * {@link OnApplyWindowInsetsListener} via the + * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener} + * method.</p> + * + * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method. + * </p> + * + * @param insets Insets to apply + * @return The provided insets minus the insets that were consumed + */ + public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { + try { + mPrivateFlags3 |= PFLAG3_APPLYING_INSETS; + if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) { + return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets); + } else { + return onApplyWindowInsets(insets); + } + } finally { + mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS; + } + } + + /** * @hide Compute the insets that should be consumed by this view and the ones * that should propagate to those under it. */ @@ -5995,6 +6121,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed. + * @deprecated Use {@link #requestApplyInsets()} for newer platform versions. */ public void requestFitSystemWindows() { if (mParent != null) { @@ -6003,6 +6130,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed. + */ + public void requestApplyInsets() { + requestFitSystemWindows(); + } + + /** * For use by PhoneWindow to make its own system window fitting optional. * @hide */ @@ -18668,6 +18802,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void onViewDetachedFromWindow(View v); } + /** + * Listener for applying window insets on a view in a custom way. + * + * <p>Apps may choose to implement this interface if they want to apply custom policy + * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener + * is set, its + * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets} + * method will be called instead of the View's own + * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener + * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply + * the View's normal behavior as part of its own.</p> + */ + public interface OnApplyWindowInsetsListener { + /** + * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set} + * on a View, this listener method will be called instead of the view's own + * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. + * + * @param v The view applying window insets + * @param insets The insets to apply + * @return The insets supplied, minus any insets that were consumed + */ + public WindowInsets onApplyWindowInsets(View v, WindowInsets insets); + } + private final class UnsetPressedState implements Runnable { public void run() { setPressed(false); |
