Skip to content

Commit 890970a

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Remove ReactImageView Legacy Background Path (facebook#46167)
Summary: Pull Request resolved: facebook#46167 ## This Diff This removes the legacy path from ReactImageView and its view manager. ## This Stack This removes the non-Style-applicator background management paths of the different native components. There have been multiple conflicting changes, and bugs added bc harder to reason about, which motivates making this change as soon as possible. This also lets us formalize guarantees that BaseViewManager may safely manipulate background styling of all built in native components. There is one still known issue, where BackgroundStyleApplicator does not propagate I18nManager derived layout direction to borders (compared to Android derived root direction). This is mostly an issue for apps that with LTR and RTL context, or force a layout direction, which I would guess is relatively rare, so my plan is to forward fix this later this by enabling set_android_layout_direction which will solve that problem mopre generically. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D61657253 fbshipit-source-id: 96cf1160e466de78c2f133f0e4fb2d9b2e7cf478
1 parent a64183b commit 890970a

File tree

3 files changed

+24
-200
lines changed

3 files changed

+24
-200
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ import com.facebook.drawee.controller.AbstractDraweeControllerBuilder
1616
import com.facebook.react.bridge.ReadableArray
1717
import com.facebook.react.bridge.ReadableMap
1818
import com.facebook.react.common.ReactConstants
19-
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
2019
import com.facebook.react.module.annotations.ReactModule
2120
import com.facebook.react.uimanager.BackgroundStyleApplicator
2221
import com.facebook.react.uimanager.LengthPercentage
2322
import com.facebook.react.uimanager.LengthPercentageType
24-
import com.facebook.react.uimanager.PixelUtil.dpToPx
2523
import com.facebook.react.uimanager.SimpleViewManager
2624
import com.facebook.react.uimanager.ThemedReactContext
2725
import com.facebook.react.uimanager.ViewProps
@@ -141,15 +139,7 @@ public constructor(
141139

142140
@ReactProp(name = "borderColor", customType = "Color")
143141
public fun setBorderColor(view: ReactImageView, borderColor: Int?) {
144-
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
145-
BackgroundStyleApplicator.setBorderColor(view, LogicalEdge.ALL, borderColor)
146-
} else {
147-
if (borderColor == null) {
148-
view.setBorderColor(Color.TRANSPARENT)
149-
} else {
150-
view.setBorderColor(borderColor)
151-
}
152-
}
142+
BackgroundStyleApplicator.setBorderColor(view, LogicalEdge.ALL, borderColor)
153143
}
154144

155145
@ReactProp(name = "overlayColor", customType = "Color")
@@ -163,11 +153,7 @@ public constructor(
163153

164154
@ReactProp(name = "borderWidth")
165155
public fun setBorderWidth(view: ReactImageView, borderWidth: Float) {
166-
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
167-
BackgroundStyleApplicator.setBorderWidth(view, LogicalEdge.ALL, borderWidth)
168-
} else {
169-
view.setBorderWidth(borderWidth)
170-
}
156+
BackgroundStyleApplicator.setBorderWidth(view, LogicalEdge.ALL, borderWidth)
171157
}
172158

173159
@ReactPropGroup(
@@ -180,24 +166,10 @@ public constructor(
180166
ViewProps.BORDER_BOTTOM_LEFT_RADIUS],
181167
defaultFloat = Float.NaN)
182168
public fun setBorderRadius(view: ReactImageView, index: Int, borderRadius: Float) {
183-
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
184-
val radius =
185-
if (borderRadius.isNaN()) null
186-
else LengthPercentage(borderRadius, LengthPercentageType.POINT)
187-
BackgroundStyleApplicator.setBorderRadius(view, BorderRadiusProp.values()[index], radius)
188-
} else {
189-
val convertedBorderRadius =
190-
if (!borderRadius.isNaN()) {
191-
borderRadius.dpToPx()
192-
} else {
193-
borderRadius
194-
}
195-
if (index == 0) {
196-
view.setBorderRadius(convertedBorderRadius)
197-
} else {
198-
view.setBorderRadius(convertedBorderRadius, index - 1)
199-
}
200-
}
169+
val radius =
170+
if (borderRadius.isNaN()) null
171+
else LengthPercentage(borderRadius, LengthPercentageType.POINT)
172+
BackgroundStyleApplicator.setBorderRadius(view, BorderRadiusProp.values()[index], radius)
201173
}
202174

203175
@ReactProp(name = ViewProps.RESIZE_MODE)
@@ -262,20 +234,14 @@ public constructor(
262234

263235
@ReactProp(name = ViewProps.BOX_SHADOW, customType = "BoxShadow")
264236
public fun setBoxShadow(view: ReactImageView, shadows: ReadableArray?): Unit {
265-
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
266-
BackgroundStyleApplicator.setBoxShadow(view, shadows)
267-
}
237+
BackgroundStyleApplicator.setBoxShadow(view, shadows)
268238
}
269239

270240
public override fun setBackgroundColor(
271241
view: ReactImageView,
272242
@ColorInt backgroundColor: Int
273243
): Unit {
274-
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
275-
BackgroundStyleApplicator.setBackgroundColor(view, backgroundColor)
276-
} else {
277-
super.setBackgroundColor(view, backgroundColor)
278-
}
244+
BackgroundStyleApplicator.setBackgroundColor(view, backgroundColor)
279245
}
280246

281247
public override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt

Lines changed: 12 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import com.facebook.drawee.controller.AbstractDraweeControllerBuilder
2828
import com.facebook.drawee.controller.ControllerListener
2929
import com.facebook.drawee.controller.ForwardingControllerListener
3030
import com.facebook.drawee.drawable.AutoRotateDrawable
31-
import com.facebook.drawee.drawable.RoundedColorDrawable
3231
import com.facebook.drawee.drawable.ScalingUtils
3332
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
3433
import com.facebook.drawee.generic.RoundingParams
@@ -49,17 +48,13 @@ import com.facebook.react.common.annotations.UnstableReactNativeAPI
4948
import com.facebook.react.common.annotations.VisibleForTesting
5049
import com.facebook.react.common.build.ReactBuildConfig
5150
import com.facebook.react.config.ReactFeatureFlags
52-
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.enableBackgroundStyleApplicator
5351
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.loadVectorDrawablesOnImages
54-
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.useNewReactImageViewBackgroundDrawing
5552
import com.facebook.react.modules.fresco.ReactNetworkImageRequest
5653
import com.facebook.react.uimanager.BackgroundStyleApplicator
57-
import com.facebook.react.uimanager.FloatUtil.floatsEqual
5854
import com.facebook.react.uimanager.LengthPercentage
5955
import com.facebook.react.uimanager.LengthPercentageType
6056
import com.facebook.react.uimanager.PixelUtil.dpToPx
6157
import com.facebook.react.uimanager.PixelUtil.pxToDp
62-
import com.facebook.react.uimanager.Spacing
6358
import com.facebook.react.uimanager.UIManagerHelper
6459
import com.facebook.react.uimanager.style.BorderRadiusProp
6560
import com.facebook.react.uimanager.style.LogicalEdge
@@ -76,8 +71,6 @@ import com.facebook.react.views.imagehelper.ImageSource
7671
import com.facebook.react.views.imagehelper.ImageSource.Companion.getTransparentBitmapImageSource
7772
import com.facebook.react.views.imagehelper.MultiSourceHelper.getBestSourceForSize
7873
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper.Companion.instance
79-
import com.facebook.react.views.view.ReactViewBackgroundManager
80-
import com.facebook.yoga.YogaConstants
8174
import kotlin.math.abs
8275

8376
/**
@@ -97,13 +90,7 @@ public class ReactImageView(
9790
private var cachedImageSource: ImageSource? = null
9891
private var defaultImageDrawable: Drawable? = null
9992
private var loadingImageDrawable: Drawable? = null
100-
private var backgroundImageDrawable: RoundedColorDrawable? = null
101-
private var backgroundColor = 0x00000000
102-
private var borderColor = 0
10393
private var overlayColor = 0
104-
private var borderWidth = 0f
105-
private var borderRadius = YogaConstants.UNDEFINED
106-
private var borderCornerRadii: FloatArray? = null
10794
private var scaleType = defaultValue()
10895
private var tileMode = defaultTileMode()
10996
private var isDirty = false
@@ -115,11 +102,9 @@ public class ReactImageView(
115102
private var progressiveRenderingEnabled = false
116103
private var headers: ReadableMap? = null
117104
private var resizeMultiplier = 1.0f
118-
private val reactBackgroundManager = ReactViewBackgroundManager(this)
119105
private var resizeMethod = ImageResizeMethod.AUTO
120106

121107
init {
122-
reactBackgroundManager.setOverflow("hidden")
123108
// Workaround Android bug where ImageView visibility is not propagated to the Drawable, so you
124109
// have to manually update visibility. Will be resolved once we move to VitoView.
125110
setLegacyVisibilityHandlingEnabled(true)
@@ -213,26 +198,11 @@ public class ReactImageView(
213198
}
214199

215200
public override fun setBackgroundColor(backgroundColor: Int) {
216-
if (enableBackgroundStyleApplicator()) {
217-
BackgroundStyleApplicator.setBackgroundColor(this, backgroundColor)
218-
} else if (useNewReactImageViewBackgroundDrawing()) {
219-
reactBackgroundManager.backgroundColor = backgroundColor
220-
} else if (this.backgroundColor != backgroundColor) {
221-
this.backgroundColor = backgroundColor
222-
backgroundImageDrawable = RoundedColorDrawable(backgroundColor)
223-
isDirty = true
224-
}
201+
BackgroundStyleApplicator.setBackgroundColor(this, backgroundColor)
225202
}
226203

227204
public fun setBorderColor(borderColor: Int) {
228-
if (enableBackgroundStyleApplicator()) {
229-
BackgroundStyleApplicator.setBorderColor(this, LogicalEdge.ALL, borderColor)
230-
} else if (useNewReactImageViewBackgroundDrawing()) {
231-
reactBackgroundManager.setBorderColor(Spacing.ALL, borderColor)
232-
} else if (this.borderColor != borderColor) {
233-
this.borderColor = borderColor
234-
isDirty = true
235-
}
205+
BackgroundStyleApplicator.setBorderColor(this, LogicalEdge.ALL, borderColor)
236206
}
237207

238208
public fun setOverlayColor(overlayColor: Int) {
@@ -243,49 +213,21 @@ public class ReactImageView(
243213
}
244214

245215
public fun setBorderWidth(borderWidth: Float) {
246-
val newBorderWidth = borderWidth.dpToPx()
247-
if (enableBackgroundStyleApplicator()) {
248-
BackgroundStyleApplicator.setBorderWidth(this, LogicalEdge.ALL, borderWidth)
249-
} else if (useNewReactImageViewBackgroundDrawing()) {
250-
reactBackgroundManager.setBorderWidth(Spacing.ALL, newBorderWidth)
251-
} else if (!floatsEqual(this.borderWidth, newBorderWidth)) {
252-
this.borderWidth = newBorderWidth
253-
isDirty = true
254-
}
216+
BackgroundStyleApplicator.setBorderWidth(this, LogicalEdge.ALL, borderWidth)
255217
}
256218

257219
public fun setBorderRadius(borderRadius: Float) {
258-
if (enableBackgroundStyleApplicator()) {
259-
val radius =
260-
if (borderRadius.isNaN()) null
261-
else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT)
262-
BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.BORDER_RADIUS, radius)
263-
} else if (useNewReactImageViewBackgroundDrawing()) {
264-
reactBackgroundManager.setBorderRadius(borderRadius)
265-
} else if (!floatsEqual(this.borderRadius, borderRadius)) {
266-
this.borderRadius = borderRadius
267-
isDirty = true
268-
}
220+
val radius =
221+
if (borderRadius.isNaN()) null
222+
else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT)
223+
BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.BORDER_RADIUS, radius)
269224
}
270225

271226
public fun setBorderRadius(borderRadius: Float, position: Int) {
272-
if (enableBackgroundStyleApplicator()) {
273-
val radius =
274-
if (borderRadius.isNaN()) null
275-
else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT)
276-
BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.values()[position], radius)
277-
} else if (useNewReactImageViewBackgroundDrawing()) {
278-
reactBackgroundManager.setBorderRadius(borderRadius, position + 1)
279-
} else {
280-
if (borderCornerRadii == null) {
281-
borderCornerRadii = FloatArray(4) { YogaConstants.UNDEFINED }
282-
}
283-
284-
if (!floatsEqual(borderCornerRadii?.get(position), borderRadius)) {
285-
borderCornerRadii?.set(position, borderRadius)
286-
isDirty = true
287-
}
288-
}
227+
val radius =
228+
if (borderRadius.isNaN()) null
229+
else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT)
230+
BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.values()[position], radius)
289231
}
290232

291233
public fun setScaleType(scaleType: ScalingUtils.ScaleType) {
@@ -395,11 +337,7 @@ public class ReactImageView(
395337
public override fun hasOverlappingRendering(): Boolean = false
396338

397339
public override fun onDraw(canvas: Canvas) {
398-
if (enableBackgroundStyleApplicator()) {
399-
BackgroundStyleApplicator.clipToPaddingBox(this, canvas)
400-
} else if (useNewReactImageViewBackgroundDrawing()) {
401-
reactBackgroundManager.maybeClipToPaddingBox(canvas)
402-
}
340+
BackgroundStyleApplicator.clipToPaddingBox(this, canvas)
403341
super.onDraw(canvas)
404342
}
405343

@@ -439,22 +377,8 @@ public class ReactImageView(
439377
hierarchy.setPlaceholderImage(loadingImageDrawable, ScalingUtils.ScaleType.CENTER)
440378
}
441379

442-
getCornerRadii(computedCornerRadii)
443-
444380
val roundingParams = hierarchy.roundingParams
445381
if (roundingParams != null) {
446-
roundingParams.setCornersRadii(
447-
computedCornerRadii[0],
448-
computedCornerRadii[1],
449-
computedCornerRadii[2],
450-
computedCornerRadii[3])
451-
452-
backgroundImageDrawable?.let { background ->
453-
background.setBorder(borderColor, borderWidth)
454-
roundingParams.cornersRadii?.let { background.radii = it }
455-
hierarchy.setBackgroundImage(background)
456-
}
457-
roundingParams.setBorder(borderColor, borderWidth)
458382
if (overlayColor != Color.TRANSPARENT) {
459383
roundingParams.setOverlayColor(overlayColor)
460384
} else {
@@ -578,16 +502,6 @@ public class ReactImageView(
578502
}
579503
}
580504

581-
private fun getCornerRadii(computedCorners: FloatArray) {
582-
val defaultBorderRadius = if (!YogaConstants.isUndefined(borderRadius)) borderRadius else 0f
583-
584-
val radii = borderCornerRadii ?: FloatArray(4) { Float.NaN }
585-
computedCorners[0] = if (!YogaConstants.isUndefined(radii[0])) radii[0] else defaultBorderRadius
586-
computedCorners[1] = if (!YogaConstants.isUndefined(radii[1])) radii[1] else defaultBorderRadius
587-
computedCorners[2] = if (!YogaConstants.isUndefined(radii[2])) radii[2] else defaultBorderRadius
588-
computedCorners[3] = if (!YogaConstants.isUndefined(radii[3])) radii[3] else defaultBorderRadius
589-
}
590-
591505
@VisibleForTesting
592506
public fun setControllerListener(controllerListener: ControllerListener<ImageInfo>?) {
593507
controllerForTesting = controllerListener
@@ -709,8 +623,6 @@ public class ReactImageView(
709623
public companion object {
710624
public const val REMOTE_IMAGE_FADE_DURATION_MS: Int = 300
711625

712-
private val computedCornerRadii = FloatArray(4)
713-
714626
// Fresco lacks support for repeating images, see https://github.com/facebook/fresco/issues/1575
715627
// We implement it here as a postprocessing step.
716628
private val tileMatrix = Matrix()

0 commit comments

Comments
 (0)