Skip to content

Commit b0fa322

Browse files
dulmandakhfacebook-github-bot
authored andcommitted
Implement Image.defaultSource property on Android
Summary: This pull request implements Image.defaultSource property on Android, using Fresco (http://frescolib.org/docs/placeholder-failure-retry.html), which will show placeholder image (local asset) while loading remote image. Implementation code is almost same with loadingIndicatorSource, but without rotation. This requires release or production to bundle local images in an APK file. This provides feature parity with iOS. Set Image.defaultSource on Android, and will show it while loading Image.source. ```JSX <Image defaultSource={require('<path to image>')} source={{uri: '<url to remote image>'}} style={{ height: 300, width: 300 }} /> ``` [ANDROID] [FEATURE] [IMAGE] - Image.defaultSource will show local image as placeholder while loading remote Image.source. Closes #18588 Differential Revision: D7540489 Pulled By: himabindugadupudi fbshipit-source-id: 908ceb659b3416e517bba64c76a31879d965ec09
1 parent bf7601f commit b0fa322

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

Libraries/Image/Image.android.js

+15
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ var Image = createReactClass({
7474
* See https://facebook.github.io/react-native/docs/image.html#blurradius
7575
*/
7676
blurRadius: PropTypes.number,
77+
/**
78+
* See https://facebook.github.io/react-native/docs/image.html#defaultsource
79+
*/
80+
defaultSource: PropTypes.number,
7781
/**
7882
* See https://facebook.github.io/react-native/docs/image.html#loadingindicatorsource
7983
*/
@@ -197,6 +201,7 @@ var Image = createReactClass({
197201

198202
render: function() {
199203
const source = resolveAssetSource(this.props.source);
204+
const defaultSource = resolveAssetSource(this.props.defaultSource);
200205
const loadingIndicatorSource = resolveAssetSource(
201206
this.props.loadingIndicatorSource,
202207
);
@@ -220,6 +225,12 @@ var Image = createReactClass({
220225
);
221226
}
222227

228+
if (this.props.defaultSource && this.props.loadingIndicatorSource) {
229+
throw new Error(
230+
'The <Image> component cannot have defaultSource and loadingIndicatorSource at the same time. Please use either defaultSource or loadingIndicatorSource.',
231+
);
232+
}
233+
223234
if (source && (source.uri || Array.isArray(source))) {
224235
let style;
225236
let sources;
@@ -243,6 +254,9 @@ var Image = createReactClass({
243254
),
244255
src: sources,
245256
headers: source.headers,
257+
defaultSrc: defaultSource
258+
? defaultSource.uri
259+
: null,
246260
loadingIndicatorSrc: loadingIndicatorSource
247261
? loadingIndicatorSource.uri
248262
: null,
@@ -268,6 +282,7 @@ var cfg = {
268282
nativeOnly: {
269283
src: true,
270284
headers: true,
285+
defaultSrc: true,
271286
loadingIndicatorSrc: true,
272287
shouldNotifyLoadEvents: true,
273288
},

ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java

+6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ public void setBlurRadius(ReactImageView view, float blurRadius) {
8888
view.setBlurRadius(blurRadius);
8989
}
9090

91+
// In JS this is Image.props.defaultSource
92+
@ReactProp(name = "defaultSrc")
93+
public void setDefaultSource(ReactImageView view, @Nullable String source) {
94+
view.setDefaultSource(source);
95+
}
96+
9197
// In JS this is Image.props.loadingIndicatorSource.uri
9298
@ReactProp(name = "loadingIndicatorSrc")
9399
public void setLoadingIndicatorSource(ReactImageView view, @Nullable String source) {

ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java

+10
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ public CloseableReference<Bitmap> process(Bitmap source, PlatformBitmapFactory b
184184

185185
private @Nullable ImageSource mImageSource;
186186
private @Nullable ImageSource mCachedImageSource;
187+
private @Nullable Drawable mDefaultImageDrawable;
187188
private @Nullable Drawable mLoadingImageDrawable;
188189
private @Nullable RoundedColorDrawable mBackgroundImageDrawable;
189190
private int mBackgroundColor = 0x00000000;
@@ -369,6 +370,11 @@ public void setSource(@Nullable ReadableArray sources) {
369370
mIsDirty = true;
370371
}
371372

373+
public void setDefaultSource(@Nullable String name) {
374+
mDefaultImageDrawable = ResourceDrawableIdHelper.getInstance().getResourceDrawable(getContext(), name);
375+
mIsDirty = true;
376+
}
377+
372378
public void setLoadingIndicatorSource(@Nullable String name) {
373379
Drawable drawable = ResourceDrawableIdHelper.getInstance().getResourceDrawable(getContext(), name);
374380
mLoadingImageDrawable =
@@ -428,6 +434,10 @@ public void maybeUpdateView() {
428434
GenericDraweeHierarchy hierarchy = getHierarchy();
429435
hierarchy.setActualImageScaleType(mScaleType);
430436

437+
if (mDefaultImageDrawable != null) {
438+
hierarchy.setPlaceholderImage(mDefaultImageDrawable, ScalingUtils.ScaleType.CENTER);
439+
}
440+
431441
if (mLoadingImageDrawable != null) {
432442
hierarchy.setPlaceholderImage(mLoadingImageDrawable, ScalingUtils.ScaleType.CENTER);
433443
}

0 commit comments

Comments
 (0)