summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java11
-rw-r--r--core/java/android/widget/ImageView.java75
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();