diff options
| -rw-r--r-- | core/java/android/view/View.java | 4 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 11 | ||||
| -rw-r--r-- | core/java/android/widget/ImageView.java | 75 |
3 files changed, 65 insertions, 25 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 20c15a4953d7..908658feb29c 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10384,7 +10384,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * ancestors or by window visibility * @return true if this view is visible to the user, not counting clipping or overlapping */ - @Visibility boolean dispatchVisibilityAggregated(boolean isVisible) { + boolean dispatchVisibilityAggregated(boolean isVisible) { final boolean thisVisible = getVisibility() == VISIBLE; // If we're not visible but something is telling us we are, ignore it. if (thisVisible || !isVisible) { @@ -15527,7 +15527,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (vis != GONE) { onWindowVisibilityChanged(vis); if (isShown()) { - // Calling onVisibilityChanged directly here since the subtree will also + // Calling onVisibilityAggregated directly here since the subtree will also // receive dispatchAttachedToWindow and this same call onVisibilityAggregated(vis == VISIBLE); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 7494b94ce713..1bb4c08bdf09 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -52,7 +52,6 @@ import android.hardware.input.InputManager; import android.media.AudioManager; import android.os.Binder; import android.os.Build; -import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -1468,6 +1467,8 @@ public final class ViewRootImpl implements ViewParent, final int viewVisibility = getHostVisibility(); final boolean viewVisibilityChanged = !mFirst && (mViewVisibility != viewVisibility || mNewSurfaceNeeded); + final boolean viewUserVisibilityChanged = !mFirst && + ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE)); WindowManager.LayoutParams params = null; if (mWindowAttributesChanged) { @@ -1541,13 +1542,7 @@ public final class ViewRootImpl implements ViewParent, if (viewVisibilityChanged) { mAttachInfo.mWindowVisibility = viewVisibility; host.dispatchWindowVisibilityChanged(viewVisibility); - - // Prior to N we didn't have dispatchVisibilityAggregated to give a more accurate - // view into when views are visible to the user or not. ImageView never dealt with - // telling its drawable about window visibility, among other things. Some apps cause - // an additional crossfade animation when windows become visible if they get this - // additional call, so only send it to new apps to avoid new visual jank. - if (host.getContext().getApplicationInfo().targetSdkVersion >= VERSION_CODES.N) { + if (viewUserVisibilityChanged) { host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE); } if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) { diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index ea0afb9cf542..aa67c8215b04 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; import android.content.res.ColorStateList; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -115,11 +114,17 @@ public class ImageView extends View { private int mBaseline = -1; private boolean mBaselineAlignBottom = false; - // AdjustViewBounds behavior will be in compatibility mode for older apps. - private boolean mAdjustViewBoundsCompat = false; + /** Compatibility modes dependent on targetSdkVersion of the app. */ + private static boolean sCompatDone; + + /** AdjustViewBounds behavior will be in compatibility mode for older apps. */ + private static boolean sCompatAdjustViewBounds; /** Whether to pass Resources when creating the source from a stream. */ - private boolean mUseCorrectStreamDensity; + private static boolean sCompatUseCorrectStreamDensity; + + /** Whether to use pre-Nougat drawable visibility dispatching conditions. */ + private static boolean sCompatDrawableVisibilityDispatch; private static final ScaleType[] sScaleTypeArray = { ScaleType.MATRIX, @@ -206,9 +211,13 @@ public class ImageView extends View { mMatrix = new Matrix(); mScaleType = ScaleType.FIT_CENTER; - final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; - mAdjustViewBoundsCompat = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1; - mUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M; + if (!sCompatDone) { + final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; + sCompatAdjustViewBounds = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1; + sCompatUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M; + sCompatDrawableVisibilityDispatch = targetSdkVersion < Build.VERSION_CODES.N; + sCompatDone = true; + } } @Override @@ -881,8 +890,8 @@ public class ImageView extends View { InputStream stream = null; try { stream = mContext.getContentResolver().openInputStream(uri); - return Drawable.createFromResourceStream( - mUseCorrectStreamDensity ? getResources() : null, null, stream, null); + return Drawable.createFromResourceStream(sCompatUseCorrectStreamDensity + ? getResources() : null, null, stream, null); } catch (Exception e) { Log.w(LOG_TAG, "Unable to open content: " + uri, e); } finally { @@ -917,10 +926,13 @@ public class ImageView extends View { mRecycleableBitmapDrawable.setBitmap(null); } + boolean sameDrawable = false; + if (mDrawable != null) { + sameDrawable = mDrawable == d; mDrawable.setCallback(null); unscheduleDrawable(mDrawable); - if (isAttachedToWindow()) { + if (!sCompatDrawableVisibilityDispatch && !sameDrawable && isAttachedToWindow()) { mDrawable.setVisible(false, false); } } @@ -933,8 +945,12 @@ public class ImageView extends View { if (d.isStateful()) { d.setState(getDrawableState()); } - d.setVisible(isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown(), - true); + if (!sameDrawable || sCompatDrawableVisibilityDispatch) { + final boolean visible = sCompatDrawableVisibilityDispatch + ? getVisibility() == VISIBLE + : isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown(); + d.setVisible(visible, true); + } d.setLevel(mLevel); mDrawableWidth = d.getIntrinsicWidth(); mDrawableHeight = d.getIntrinsicHeight(); @@ -1057,7 +1073,7 @@ public class ImageView extends View { pleft + pright; // Allow the width to outgrow its original estimate if height is fixed. - if (!resizeHeight && !mAdjustViewBoundsCompat) { + if (!resizeHeight && !sCompatAdjustViewBounds) { widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec); } @@ -1073,7 +1089,7 @@ public class ImageView extends View { ptop + pbottom; // Allow the height to outgrow its original estimate if width is fixed. - if (!resizeWidth && !mAdjustViewBoundsCompat) { + if (!resizeWidth && !sCompatAdjustViewBounds) { heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightMeasureSpec); } @@ -1512,11 +1528,40 @@ public class ImageView extends View { @Override public void onVisibilityAggregated(boolean isVisible) { super.onVisibilityAggregated(isVisible); - if (mDrawable != null) { + // Only do this for new apps post-Nougat + if (mDrawable != null && !sCompatDrawableVisibilityDispatch) { mDrawable.setVisible(isVisible, false); } } + @RemotableViewMethod + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated + if (mDrawable != null && sCompatDrawableVisibilityDispatch) { + mDrawable.setVisible(visibility == VISIBLE, false); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated + if (mDrawable != null && sCompatDrawableVisibilityDispatch) { + mDrawable.setVisible(getVisibility() == VISIBLE, false); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated + if (mDrawable != null && sCompatDrawableVisibilityDispatch) { + mDrawable.setVisible(false, false); + } + } + @Override public CharSequence getAccessibilityClassName() { return ImageView.class.getName(); |