From 7320ca5c7a97ae1e6b58fc611536f7a2c36df9a7 Mon Sep 17 00:00:00 2001 From: Felix Oghina Date: Fri, 29 Sep 2017 08:37:22 -0700 Subject: [PATCH] Add GlobalImageLoadListener Reviewed By: AaaChiuuu Differential Revision: D5932865 fbshipit-source-id: 700983d7fc44c4ee5f77b58ef54cec62869009e0 --- .../react/flat/DrawImageWithDrawee.java | 18 ++++++++----- .../react/flat/RCTImageViewManager.java | 13 ++++++++-- .../views/image/GlobalImageLoadListener.java | 12 +++++++++ .../react/views/image/ReactImageManager.java | 21 ++++++++------- .../react/views/image/ReactImageView.java | 26 +++++++++++-------- 5 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/image/GlobalImageLoadListener.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java index f9d37a1b2..da506de63 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java @@ -9,18 +9,12 @@ package com.facebook.react.flat; -import javax.annotation.Nullable; - -import java.util.LinkedList; -import java.util.List; - import android.content.Context; import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Animatable; import android.net.Uri; - import com.facebook.drawee.controller.ControllerListener; import com.facebook.drawee.drawable.ScalingUtils.ScaleType; import com.facebook.drawee.generic.GenericDraweeHierarchy; @@ -31,12 +25,16 @@ import com.facebook.imagepipeline.request.ImageRequestBuilder; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.views.image.GlobalImageLoadListener; import com.facebook.react.views.image.ImageLoadEvent; import com.facebook.react.views.image.ImageResizeMode; import com.facebook.react.views.image.ReactImageView; import com.facebook.react.views.imagehelper.ImageSource; import com.facebook.react.views.imagehelper.MultiSourceHelper; import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; +import java.util.LinkedList; +import java.util.List; +import javax.annotation.Nullable; /** * DrawImageWithDrawee is a DrawCommand that can draw a local or remote image. @@ -48,6 +46,7 @@ import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; private static final String LOCAL_CONTENT_SCHEME = "content"; private final List mSources = new LinkedList<>(); + private final @Nullable GlobalImageLoadListener mGlobalImageLoadListener; private @Nullable DraweeRequestHelper mRequestHelper; private @Nullable PorterDuffColorFilter mColorFilter; private ScaleType mScaleType = ImageResizeMode.defaultValue(); @@ -59,6 +58,10 @@ import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; private int mFadeDuration = ReactImageView.REMOTE_IMAGE_FADE_DURATION_MS; private @Nullable FlatViewGroup.InvalidateCallback mCallback; + public DrawImageWithDrawee(@Nullable GlobalImageLoadListener globalImageLoadListener) { + mGlobalImageLoadListener = globalImageLoadListener; + } + @Override public boolean hasImageRequest() { return !mSources.isEmpty(); @@ -274,6 +277,9 @@ import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; .setResizeOptions(resizeOptions) .setProgressiveRenderingEnabled(mProgressiveRenderingEnabled) .build(); + if (mGlobalImageLoadListener != null) { + mGlobalImageLoadListener.onLoadAttempt(source.getUri()); + } ImageRequest cachedImageRequest = null; if (cachedSource != null) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/RCTImageViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/RCTImageViewManager.java index 2e504a11b..7813bc224 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/RCTImageViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/RCTImageViewManager.java @@ -11,7 +11,7 @@ package com.facebook.react.flat; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.controller.AbstractDraweeControllerBuilder; - +import com.facebook.react.views.image.GlobalImageLoadListener; import javax.annotation.Nullable; public final class RCTImageViewManager extends FlatViewManager { @@ -19,6 +19,7 @@ public final class RCTImageViewManager extends FlatViewManager { /* package */ static final String REACT_CLASS = "RCTImageView"; private @Nullable AbstractDraweeControllerBuilder mDraweeControllerBuilder; + private @Nullable GlobalImageLoadListener mGlobalImageLoadListener; private final @Nullable Object mCallerContext; public RCTImageViewManager() { @@ -28,7 +29,15 @@ public final class RCTImageViewManager extends FlatViewManager { public RCTImageViewManager( AbstractDraweeControllerBuilder draweeControllerBuilder, Object callerContext) { + this(draweeControllerBuilder, null, callerContext); + } + + public RCTImageViewManager( + AbstractDraweeControllerBuilder draweeControllerBuilder, + @Nullable GlobalImageLoadListener globalImageLoadListener, + Object callerContext) { mDraweeControllerBuilder = draweeControllerBuilder; + mGlobalImageLoadListener = globalImageLoadListener; mCallerContext = callerContext; } @@ -39,7 +48,7 @@ public final class RCTImageViewManager extends FlatViewManager { @Override public RCTImageView createShadowNodeInstance() { - return new RCTImageView(new DrawImageWithDrawee()); + return new RCTImageView(new DrawImageWithDrawee(mGlobalImageLoadListener)); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/GlobalImageLoadListener.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/GlobalImageLoadListener.java new file mode 100644 index 000000000..f8df20157 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/GlobalImageLoadListener.java @@ -0,0 +1,12 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.react.views.image; + +import android.net.Uri; + +/** Listener interface for global image loading events. */ +public interface GlobalImageLoadListener { + + /** Called when a source has been set on an ImageView, but before it is actually loaded. */ + void onLoadAttempt(Uri uri); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java index 78813eefa..e77fd6fd9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java @@ -9,14 +9,8 @@ package com.facebook.react.views.image; -import javax.annotation.Nullable; - -import java.util.Map; - import android.graphics.Color; import android.graphics.PorterDuff.Mode; - -import com.facebook.yoga.YogaConstants; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.controller.AbstractDraweeControllerBuilder; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; @@ -30,6 +24,9 @@ import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; +import com.facebook.yoga.YogaConstants; +import java.util.Map; +import javax.annotation.Nullable; @ReactModule(name = ReactImageManager.REACT_CLASS) public class ReactImageManager extends SimpleViewManager { @@ -42,12 +39,20 @@ public class ReactImageManager extends SimpleViewManager { } private @Nullable AbstractDraweeControllerBuilder mDraweeControllerBuilder; + private @Nullable GlobalImageLoadListener mGlobalImageLoadListener; private final @Nullable Object mCallerContext; + public ReactImageManager( + AbstractDraweeControllerBuilder draweeControllerBuilder, Object callerContext) { + this(draweeControllerBuilder, null, callerContext); + } + public ReactImageManager( AbstractDraweeControllerBuilder draweeControllerBuilder, + @Nullable GlobalImageLoadListener globalImageLoadListener, Object callerContext) { mDraweeControllerBuilder = draweeControllerBuilder; + mGlobalImageLoadListener = globalImageLoadListener; mCallerContext = callerContext; } @@ -71,9 +76,7 @@ public class ReactImageManager extends SimpleViewManager { @Override public ReactImageView createViewInstance(ThemedReactContext context) { return new ReactImageView( - context, - getDraweeControllerBuilder(), - getCallerContext()); + context, getDraweeControllerBuilder(), mGlobalImageLoadListener, getCallerContext()); } // In JS this is Image.props.source diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java index 4d65e5141..30b73bc51 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java @@ -9,12 +9,6 @@ package com.facebook.react.views.image; -import javax.annotation.Nullable; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; @@ -30,10 +24,7 @@ import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.widget.Toast; - import com.facebook.common.util.UriUtil; -import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.yoga.YogaConstants; import com.facebook.drawee.controller.AbstractDraweeControllerBuilder; import com.facebook.drawee.controller.BaseControllerListener; import com.facebook.drawee.controller.ControllerListener; @@ -54,15 +45,21 @@ import com.facebook.imagepipeline.request.Postprocessor; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.uimanager.FloatUtil; +import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.modules.fresco.ReactNetworkImageRequest; +import com.facebook.react.uimanager.FloatUtil; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.views.imagehelper.ImageSource; import com.facebook.react.views.imagehelper.MultiSourceHelper; -import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper; import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; +import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper; +import com.facebook.yoga.YogaConstants; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import javax.annotation.Nullable; /** * Wrapper class around Fresco's GenericDraweeView, enabling persisting props across multiple view @@ -163,6 +160,7 @@ public class ReactImageView extends GenericDraweeView { private @Nullable IterativeBoxBlurPostProcessor mIterativeBoxBlurPostProcessor; private @Nullable ControllerListener mControllerListener; private @Nullable ControllerListener mControllerForTesting; + private @Nullable GlobalImageLoadListener mGlobalImageLoadListener; private final @Nullable Object mCallerContext; private int mFadeDurationMs = -1; private boolean mProgressiveRenderingEnabled; @@ -178,11 +176,13 @@ public class ReactImageView extends GenericDraweeView { public ReactImageView( Context context, AbstractDraweeControllerBuilder draweeControllerBuilder, + @Nullable GlobalImageLoadListener globalImageLoadListener, @Nullable Object callerContext) { super(context, buildHierarchy(context)); mScaleType = ImageResizeMode.defaultValue(); mDraweeControllerBuilder = draweeControllerBuilder; mRoundedCornerPostprocessor = new RoundedCornerPostprocessor(); + mGlobalImageLoadListener = globalImageLoadListener; mCallerContext = callerContext; mSources = new LinkedList<>(); } @@ -416,6 +416,10 @@ public class ReactImageView extends GenericDraweeView { ImageRequest imageRequest = ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, mHeaders); + if (mGlobalImageLoadListener != null) { + mGlobalImageLoadListener.onLoadAttempt(mImageSource.getUri()); + } + // This builder is reused mDraweeControllerBuilder.reset();