diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt index 9e8c8bcf8438..116ed4ce00df 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt @@ -259,6 +259,18 @@ internal object ViewManagersPropertyCache { } } + private class BoxedFloatPropSetter(prop: ReactProp, setter: Method) : + PropSetter(prop, "number", setter) { + + override fun getValueOrDefault(value: Any?, context: Context): Any? { + if (value != null) { + // All numbers from JS are Doubles which can't be simply cast to Float + return if (value is Double) value.toFloat() else value as Float + } + return null + } + } + private class BoxedIntPropSetter : PropSetter { constructor(prop: ReactProp, setter: Method) : super(prop, "number", setter) @@ -391,6 +403,7 @@ internal object ViewManagersPropertyCache { DoublePropSetter(annotation, method, annotation.defaultDouble) String::class.java -> StringPropSetter(annotation, method) java.lang.Boolean::class.java -> BoxedBooleanPropSetter(annotation, method) + java.lang.Float::class.java -> BoxedFloatPropSetter(annotation, method) java.lang.Integer::class.java -> if ("Color" == annotation.customType) { BoxedColorPropSetter(annotation, method) diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactPropAnnotationSetterTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactPropAnnotationSetterTest.kt index 0813c85acaa6..c04465036908 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactPropAnnotationSetterTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactPropAnnotationSetterTest.kt @@ -39,6 +39,8 @@ class ReactPropAnnotationSetterTest { fun onBoxedBooleanSetterCalled(value: Boolean?) + fun onBoxedFloatSetterCalled(value: Float?) + fun onBoxedIntSetterCalled(value: Int?) fun onArraySetterCalled(value: ReadableArray?) @@ -128,6 +130,11 @@ class ReactPropAnnotationSetterTest { viewManagerUpdatesReceiver.onBoxedIntSetterCalled(value) } + @ReactProp(name = "boxedFloatProp") + fun setBoxedFloatProp(v: View?, value: Float?) { + viewManagerUpdatesReceiver.onBoxedFloatSetterCalled(value) + } + @ReactProp(name = "arrayProp") fun setArrayProp(v: View?, value: ReadableArray?) { viewManagerUpdatesReceiver.onArraySetterCalled(value) @@ -314,6 +321,22 @@ class ReactPropAnnotationSetterTest { Mockito.reset(updatesReceiverMock) } + @Test + fun testBoxedFloatSetter() { + viewManager.updateProperties(targetView, buildStyles("boxedFloatProp", 3.5)) + Mockito.verify(updatesReceiverMock).onBoxedFloatSetterCalled(3.5f) + Mockito.verifyNoMoreInteractions(updatesReceiverMock) + Mockito.reset(updatesReceiverMock) + viewManager.updateProperties(targetView, buildStyles("boxedFloatProp", -7.0)) + Mockito.verify(updatesReceiverMock).onBoxedFloatSetterCalled(-7.0f) + Mockito.verifyNoMoreInteractions(updatesReceiverMock) + Mockito.reset(updatesReceiverMock) + viewManager.updateProperties(targetView, buildStyles("boxedFloatProp", null)) + Mockito.verify(updatesReceiverMock).onBoxedFloatSetterCalled(null) + Mockito.verifyNoMoreInteractions(updatesReceiverMock) + Mockito.reset(updatesReceiverMock) + } + @Test fun testArraySetter() { val array: ReadableArray = JavaOnlyArray()