Loading core/java/android/view/View.java +52 −2 Original line number Diff line number Diff line Loading @@ -3506,6 +3506,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG4_AUTOFILL_HIDE_HIGHLIGHT * 11 PFLAG4_SCROLL_CAPTURE_HINT_MASK * 1 PFLAG4_ALLOW_CLICK_WHEN_DISABLED * 1 PFLAG4_DETACHED * |-------|-------|-------|-------| */ Loading Loading @@ -3567,6 +3568,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG4_ALLOW_CLICK_WHEN_DISABLED = 0x000001000; /** * Indicates if the view is just detached. */ private static final int PFLAG4_DETACHED = 0x000002000; /* End of masks for mPrivateFlags4 */ /** @hide */ Loading Loading @@ -8330,7 +8336,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); boolean isWindowDisappearedEvent = isWindowStateChanged && ((event.getContentChangeTypes() & AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED) != 0); if (!isShown() && !isWindowDisappearedEvent) { boolean detached = detached(); if (!isShown() && !isWindowDisappearedEvent && !detached) { return; } onInitializeAccessibilityEvent(event); Loading @@ -8341,6 +8348,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, SendAccessibilityEventThrottle throttle = getThrottleForAccessibilityEvent(event); if (throttle != null) { throttle.post(event); } else if (!isWindowDisappearedEvent && detached) { // Views could be attached soon later. Accessibility events during this temporarily // detached period should be sent too. postDelayed(() -> { if (AccessibilityManager.getInstance(mContext).isEnabled() && isShown()) { requestParentSendAccessibilityEvent(event); } }, ViewConfiguration.getSendRecurringAccessibilityEventsInterval()); } else { requestParentSendAccessibilityEvent(event); } Loading Loading @@ -11126,6 +11141,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return false; } private boolean detached() { View current = this; //noinspection ConstantConditions do { if ((current.mPrivateFlags4 & PFLAG4_DETACHED) != 0) { return true; } ViewParent parent = current.mParent; if (parent == null) { return false; } if (!(parent instanceof View)) { return false; } current = (View) parent; } while (current != null); return false; } /** * Called by the view hierarchy when the content insets for a window have * changed, to allow it to adjust its content to fit within those windows. Loading Loading @@ -29460,7 +29495,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Override public void run() { if (AccessibilityManager.getInstance(mContext).isEnabled()) { if (AccessibilityManager.getInstance(mContext).isEnabled() && isShown()) { requestParentSendAccessibilityEvent(mAccessibilityEvent); } reset(); Loading Loading @@ -30449,4 +30484,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } /** * Set the view to be detached or not detached. * * @param detached Whether the view is detached. * * @hide */ protected void setDetached(boolean detached) { if (detached) { mPrivateFlags4 |= PFLAG4_DETACHED; } else { mPrivateFlags4 &= ~PFLAG4_DETACHED; } } } core/java/android/view/ViewGroup.java +11 −0 Original line number Diff line number Diff line Loading @@ -5811,6 +5811,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK & ~PFLAG_DRAWING_CACHE_VALID) | PFLAG_DRAWN | PFLAG_INVALIDATED; child.setDetached(false); this.mPrivateFlags |= PFLAG_INVALIDATED; if (child.hasFocus()) { Loading Loading @@ -5839,6 +5840,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewFromParent(View child) { child.setDetached(true); removeFromArray(indexOfChild(child)); } Loading @@ -5860,6 +5862,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewFromParent(int index) { if (index >= 0 && index < mChildrenCount) { mChildren[index].setDetached(true); } removeFromArray(index); } Loading @@ -5882,6 +5887,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewsFromParent(int start, int count) { start = Math.max(0, start); final int end = Math.min(mChildrenCount, start + count); for (int i = start; i < end; i++) { mChildren[i].setDetached(true); } removeFromArray(start, count); } Loading Loading @@ -5911,6 +5921,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = count - 1; i >= 0; i--) { children[i].mParent = null; children[i].setDetached(true); children[i] = null; } } Loading core/java/android/widget/CompoundButton.java +5 −3 Original line number Diff line number Diff line Loading @@ -183,14 +183,14 @@ public abstract class CompoundButton extends Button implements Checkable { public void setStateDescription(@Nullable CharSequence stateDescription) { mCustomStateDescription = stateDescription; if (stateDescription == null) { setDefaultStateDescritption(); setDefaultStateDescription(); } else { super.setStateDescription(stateDescription); } } /** @hide **/ protected void setDefaultStateDescritption() { protected void setDefaultStateDescription() { if (mCustomStateDescription == null) { super.setStateDescription(getButtonStateDescription()); } Loading @@ -210,6 +210,8 @@ public abstract class CompoundButton extends Button implements Checkable { // Avoid infinite recursions if setChecked() is called from a listener if (mBroadcasting) { // setStateDescription will not send out event if the description is unchanged. setDefaultStateDescription(); return; } Loading @@ -228,7 +230,7 @@ public abstract class CompoundButton extends Button implements Checkable { mBroadcasting = false; } // setStateDescription will not send out event if the description is unchanged. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading core/java/android/widget/Switch.java +3 −3 Original line number Diff line number Diff line Loading @@ -311,7 +311,7 @@ public class Switch extends CompoundButton { refreshDrawableState(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); setChecked(isChecked()); } Loading Loading @@ -856,7 +856,7 @@ public class Switch extends CompoundButton { requestLayout(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading @@ -879,7 +879,7 @@ public class Switch extends CompoundButton { requestLayout(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading core/java/android/widget/ToggleButton.java +3 −3 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class ToggleButton extends CompoundButton { syncTextState(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); a.recycle(); } Loading Loading @@ -111,7 +111,7 @@ public class ToggleButton extends CompoundButton { mTextOn = textOn; // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading @@ -133,7 +133,7 @@ public class ToggleButton extends CompoundButton { mTextOff = textOff; // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading Loading
core/java/android/view/View.java +52 −2 Original line number Diff line number Diff line Loading @@ -3506,6 +3506,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG4_AUTOFILL_HIDE_HIGHLIGHT * 11 PFLAG4_SCROLL_CAPTURE_HINT_MASK * 1 PFLAG4_ALLOW_CLICK_WHEN_DISABLED * 1 PFLAG4_DETACHED * |-------|-------|-------|-------| */ Loading Loading @@ -3567,6 +3568,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG4_ALLOW_CLICK_WHEN_DISABLED = 0x000001000; /** * Indicates if the view is just detached. */ private static final int PFLAG4_DETACHED = 0x000002000; /* End of masks for mPrivateFlags4 */ /** @hide */ Loading Loading @@ -8330,7 +8336,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); boolean isWindowDisappearedEvent = isWindowStateChanged && ((event.getContentChangeTypes() & AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED) != 0); if (!isShown() && !isWindowDisappearedEvent) { boolean detached = detached(); if (!isShown() && !isWindowDisappearedEvent && !detached) { return; } onInitializeAccessibilityEvent(event); Loading @@ -8341,6 +8348,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, SendAccessibilityEventThrottle throttle = getThrottleForAccessibilityEvent(event); if (throttle != null) { throttle.post(event); } else if (!isWindowDisappearedEvent && detached) { // Views could be attached soon later. Accessibility events during this temporarily // detached period should be sent too. postDelayed(() -> { if (AccessibilityManager.getInstance(mContext).isEnabled() && isShown()) { requestParentSendAccessibilityEvent(event); } }, ViewConfiguration.getSendRecurringAccessibilityEventsInterval()); } else { requestParentSendAccessibilityEvent(event); } Loading Loading @@ -11126,6 +11141,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return false; } private boolean detached() { View current = this; //noinspection ConstantConditions do { if ((current.mPrivateFlags4 & PFLAG4_DETACHED) != 0) { return true; } ViewParent parent = current.mParent; if (parent == null) { return false; } if (!(parent instanceof View)) { return false; } current = (View) parent; } while (current != null); return false; } /** * Called by the view hierarchy when the content insets for a window have * changed, to allow it to adjust its content to fit within those windows. Loading Loading @@ -29460,7 +29495,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Override public void run() { if (AccessibilityManager.getInstance(mContext).isEnabled()) { if (AccessibilityManager.getInstance(mContext).isEnabled() && isShown()) { requestParentSendAccessibilityEvent(mAccessibilityEvent); } reset(); Loading Loading @@ -30449,4 +30484,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } /** * Set the view to be detached or not detached. * * @param detached Whether the view is detached. * * @hide */ protected void setDetached(boolean detached) { if (detached) { mPrivateFlags4 |= PFLAG4_DETACHED; } else { mPrivateFlags4 &= ~PFLAG4_DETACHED; } } }
core/java/android/view/ViewGroup.java +11 −0 Original line number Diff line number Diff line Loading @@ -5811,6 +5811,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK & ~PFLAG_DRAWING_CACHE_VALID) | PFLAG_DRAWN | PFLAG_INVALIDATED; child.setDetached(false); this.mPrivateFlags |= PFLAG_INVALIDATED; if (child.hasFocus()) { Loading Loading @@ -5839,6 +5840,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewFromParent(View child) { child.setDetached(true); removeFromArray(indexOfChild(child)); } Loading @@ -5860,6 +5862,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewFromParent(int index) { if (index >= 0 && index < mChildrenCount) { mChildren[index].setDetached(true); } removeFromArray(index); } Loading @@ -5882,6 +5887,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #removeDetachedView(View, boolean) */ protected void detachViewsFromParent(int start, int count) { start = Math.max(0, start); final int end = Math.min(mChildrenCount, start + count); for (int i = start; i < end; i++) { mChildren[i].setDetached(true); } removeFromArray(start, count); } Loading Loading @@ -5911,6 +5921,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = count - 1; i >= 0; i--) { children[i].mParent = null; children[i].setDetached(true); children[i] = null; } } Loading
core/java/android/widget/CompoundButton.java +5 −3 Original line number Diff line number Diff line Loading @@ -183,14 +183,14 @@ public abstract class CompoundButton extends Button implements Checkable { public void setStateDescription(@Nullable CharSequence stateDescription) { mCustomStateDescription = stateDescription; if (stateDescription == null) { setDefaultStateDescritption(); setDefaultStateDescription(); } else { super.setStateDescription(stateDescription); } } /** @hide **/ protected void setDefaultStateDescritption() { protected void setDefaultStateDescription() { if (mCustomStateDescription == null) { super.setStateDescription(getButtonStateDescription()); } Loading @@ -210,6 +210,8 @@ public abstract class CompoundButton extends Button implements Checkable { // Avoid infinite recursions if setChecked() is called from a listener if (mBroadcasting) { // setStateDescription will not send out event if the description is unchanged. setDefaultStateDescription(); return; } Loading @@ -228,7 +230,7 @@ public abstract class CompoundButton extends Button implements Checkable { mBroadcasting = false; } // setStateDescription will not send out event if the description is unchanged. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading
core/java/android/widget/Switch.java +3 −3 Original line number Diff line number Diff line Loading @@ -311,7 +311,7 @@ public class Switch extends CompoundButton { refreshDrawableState(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); setChecked(isChecked()); } Loading Loading @@ -856,7 +856,7 @@ public class Switch extends CompoundButton { requestLayout(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading @@ -879,7 +879,7 @@ public class Switch extends CompoundButton { requestLayout(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading
core/java/android/widget/ToggleButton.java +3 −3 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class ToggleButton extends CompoundButton { syncTextState(); // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); a.recycle(); } Loading Loading @@ -111,7 +111,7 @@ public class ToggleButton extends CompoundButton { mTextOn = textOn; // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading @@ -133,7 +133,7 @@ public class ToggleButton extends CompoundButton { mTextOff = textOff; // Default state is derived from on/off-text, so state has to be updated when on/off-text // are updated. setDefaultStateDescritption(); setDefaultStateDescription(); } /** Loading