From c2198a5f06817db49cd30b555c6669b33a3b15be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Thu, 13 Feb 2025 23:17:48 +0100 Subject: [PATCH 1/2] Kotlinify ReactClippingViewGroup --- .../uimanager/ReactClippingViewGroup.java | 57 ------------------- .../react/uimanager/ReactClippingViewGroup.kt | 54 ++++++++++++++++++ ...eactHorizontalScrollContainerLegacyView.kt | 18 +++--- 3 files changed, 63 insertions(+), 66 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.java deleted file mode 100644 index 9430dcd7f4ef..000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.uimanager; - -import android.graphics.Rect; -import android.view.View; - -/** - * Interface that should be implemented by {@link View} subclasses that support {@code - * removeClippedSubviews} property. When this property is set for the {@link ViewGroup} subclass - * it's responsible for detaching it's child views that are clipped by the view boundaries. Those - * view boundaries should be determined based on it's parent clipping area and current view's offset - * in parent and doesn't necessarily reflect the view visible area (in a sense of a value that - * {@link View#getGlobalVisibleRect} may return). In order to determine the clipping rect for - * current view helper method {@link ReactClippingViewGroupHelper#calculateClippingRect} can be used - * that takes into account parent view settings. - */ -public interface ReactClippingViewGroup { - - /** - * Notify view that clipping area may have changed and it should recalculate the list of children - * that should be attached/detached. This method should be called only when property {@code - * removeClippedSubviews} is set to {@code true} on a view. - * - *

CAUTION: Views are responsible for calling {@link #updateClippingRect} on it's children. - * This should happen if child implement {@link ReactClippingViewGroup}, return true from {@link - * #getRemoveClippedSubviews} and clipping rect change of the current view may affect clipping - * rect of this child. - */ - void updateClippingRect(); - - /** - * Get rectangular bounds to which view is currently clipped to. Called only on views that has set - * {@code removeCLippedSubviews} property value to {@code true}. - * - * @param outClippingRect output clipping rect should be written to this object. - */ - void getClippingRect(Rect outClippingRect); - - /** - * Sets property {@code removeClippedSubviews} as a result of property update in JS. Should be - * called only from @{link ViewManager#updateView} method. - * - *

Helper method {@link ReactClippingViewGroupHelper#applyRemoveClippedSubviewsProperty} may be - * used by {@link ViewManager} subclass to apply this property based on property update map {@link - * ReactStylesDiffMap}. - */ - void setRemoveClippedSubviews(boolean removeClippedSubviews); - - /** Get the current value of {@code removeClippedSubviews} property. */ - boolean getRemoveClippedSubviews(); -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt new file mode 100644 index 000000000000..6dd2cbd6f176 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.uimanager + +import android.graphics.Rect +import android.view.View + +/** + * Interface that should be implemented by [View] subclasses that support `removeClippedSubviews` property. When this property is set for the [ViewGroup] subclass + * it's responsible for detaching it's child views that are clipped by the view boundaries. Those + * view boundaries should be determined based on it's parent clipping area and current view's offset + * in parent and doesn't necessarily reflect the view visible area (in a sense of a value that + * [View.getGlobalVisibleRect] may return). In order to determine the clipping rect for + * current view helper method [ReactClippingViewGroupHelper.calculateClippingRect] can be used + * that takes into account parent view settings. + */ +public interface ReactClippingViewGroup { + /** + * Notify view that clipping area may have changed and it should recalculate the list of children + * that should be attached/detached. This method should be called only when property `removeClippedSubviews` is set to `true` on a view. + * + * + * CAUTION: Views are responsible for calling [updateClippingRect] on it's children. + * This should happen if child implement [ReactClippingViewGroup], return true from [getRemoveClippedSubviews] and clipping rect change of the current view may affect clipping + * rect of this child. + */ + public fun updateClippingRect() + + /** + * Get rectangular bounds to which view is currently clipped to. Called only on views that has set + * `removeCLippedSubviews` property value to `true`. + * + * @param outClippingRect output clipping rect should be written to this object. + */ + public fun getClippingRect(outClippingRect: Rect) + + /** + * Sets property `removeClippedSubviews` as a result of property update in JS. Should be + * called only from [ViewManager.updateView] method. + * + * + * Helper method [ReactClippingViewGroupHelper.applyRemoveClippedSubviewsProperty] may be + * used by [ViewManager] subclass to apply this property based on property update map [ReactStylesDiffMap]. + */ + @get:Deprecated("Use removeClippedSubviews property instead", ReplaceWith("removeClippedSubviews")) + @Suppress("INAPPLICABLE_JVM_NAME") + @get:JvmName("getRemoveClippedSubviews") + public var removeClippedSubviews: Boolean +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerLegacyView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerLegacyView.kt index 84c7647053a4..04e8f3a4bcaf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerLegacyView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerLegacyView.kt @@ -19,17 +19,17 @@ internal class ReactHorizontalScrollContainerLegacyView(context: Context) : ReactViewGroup(context) { private val isRTL: Boolean = I18nUtil.instance.isRTL(context) - override fun setRemoveClippedSubviews(removeClippedSubviews: Boolean) { - // removeClippedSubviews logic may read metrics before the offsetting we do in onLayout() and is - // such unsafe - if (isRTL) { - super.setRemoveClippedSubviews(false) - return + override var removeClippedSubviews: Boolean = false + set(value) { + // removeClippedSubviews logic may read metrics before the offsetting we do in onLayout() and + // is such unsafe + if (isRTL) { + field = false + } else { + field = value + } } - super.setRemoveClippedSubviews(removeClippedSubviews) - } - protected override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { if (isRTL) { // When the layout direction is RTL, we expect Yoga to give us a layout From 121ef7aba51e14e5c78733f9800e73b13c2bab7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Fri, 14 Feb 2025 16:04:19 +0100 Subject: [PATCH 2/2] Remove unnnecessary annotations for backwards compatibility --- .../com/facebook/react/uimanager/ReactClippingViewGroup.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt index 6dd2cbd6f176..457a8244ca2c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroup.kt @@ -24,7 +24,6 @@ public interface ReactClippingViewGroup { * Notify view that clipping area may have changed and it should recalculate the list of children * that should be attached/detached. This method should be called only when property `removeClippedSubviews` is set to `true` on a view. * - * * CAUTION: Views are responsible for calling [updateClippingRect] on it's children. * This should happen if child implement [ReactClippingViewGroup], return true from [getRemoveClippedSubviews] and clipping rect change of the current view may affect clipping * rect of this child. @@ -43,12 +42,8 @@ public interface ReactClippingViewGroup { * Sets property `removeClippedSubviews` as a result of property update in JS. Should be * called only from [ViewManager.updateView] method. * - * * Helper method [ReactClippingViewGroupHelper.applyRemoveClippedSubviewsProperty] may be * used by [ViewManager] subclass to apply this property based on property update map [ReactStylesDiffMap]. */ - @get:Deprecated("Use removeClippedSubviews property instead", ReplaceWith("removeClippedSubviews")) - @Suppress("INAPPLICABLE_JVM_NAME") - @get:JvmName("getRemoveClippedSubviews") public var removeClippedSubviews: Boolean }