diff options
| author | Adam Powell <adamp@google.com> | 2014-02-03 10:16:49 -0800 |
|---|---|---|
| committer | Adam Powell <adamp@google.com> | 2014-04-15 10:30:25 -0700 |
| commit | 50d7bfd8224f9da170dac668888bcf0831373051 (patch) | |
| tree | 7416f75033dc914e5cbf7ff2a63b857c42eba098 /core/java/android/view/View.java | |
| parent | 66e99c46546bf34fb8806dbefdbd71df1d41c814 (diff) | |
| download | frameworks_base-50d7bfd8224f9da170dac668888bcf0831373051.zip frameworks_base-50d7bfd8224f9da170dac668888bcf0831373051.tar.gz frameworks_base-50d7bfd8224f9da170dac668888bcf0831373051.tar.bz2 | |
DO NOT MERGE Refactoring of fitSystemWindows to applyWindowInsets for views
Applying insets is now handled by:
* WindowInsets class - Encapsulate system insets and local decor
insets into a single object, written specifically so that new inset
categories may be added later. Apps cannot construct their own
WindowInsets, only clone with optional modifications. This is to
prevent losing data in the event of new insets added in the future.
* onApplyWindowInsets - Actually perform the application of insets.
* OnApplyWindowInsetsListener - Allow an app to use a separate
Listener object to apply insets to a View. This allows for things
like support lib integration in custom views written for older
versions where the verifier would otherwise complain about the use
of the new WindowInsets class as a method parameter. It also allows
for applying insets in a custom way without writing a custom view.
* dispatchApplyWindowInsets - Dispatch the call to self and children
in turn, if applicable. An OnApplyWindowInsetsListener will override
the behavior of the view's default onApplyWindowInsets method; a
listener wishing to call down to the 'superclass' implementation as
part of its own operation should call view.onApplyWindowInsets. App
code should generally not override this method and instead override
onApplyWindowInsets or provide a listener.
Compatibility support with the existing fitSystemWindows method has
been provided in both directions: for code that previously called
fitSystemWindows on arbitrary views and also for code that overrode
the fitSystemWindows method in custom views. A view that supports the
newer onApplyWindowInsets mechanism should not mix that behavior with
other calls to fitSystemWindows or vice versa. Support lib-style code
should take care to consistently use one mechanism or the other at
runtime.
Change-Id: Ie88b96e0382beb5d3c3f6cd013f7043acbc0a105
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); |
