From c53d3e190109cb82f58bac3b8fec029628eaa04c Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Wed, 6 Nov 2024 15:19:38 -0800 Subject: [PATCH] xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java (#47431) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47431 Convert Java to Kotlin Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65430703 fbshipit-source-id: a1fcab2dd577fe67a1507c330466dabe7483c843 --- .../ReactAndroid/api/ReactAndroid.api | 18 +-- .../uimanager/util/ReactFindViewUtil.java | 138 ------------------ .../react/uimanager/util/ReactFindViewUtil.kt | 129 ++++++++++++++++ 3 files changed, 138 insertions(+), 147 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index f4565cf70f3..19d74b8100c 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6099,15 +6099,15 @@ public final class com/facebook/react/uimanager/style/Overflow$Companion { public final fun fromString (Ljava/lang/String;)Lcom/facebook/react/uimanager/style/Overflow; } -public class com/facebook/react/uimanager/util/ReactFindViewUtil { - public fun ()V - public static fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V - public static fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View; - public static fun notifyViewRendered (Landroid/view/View;)V - public static fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V +public final class com/facebook/react/uimanager/util/ReactFindViewUtil { + public static final field INSTANCE Lcom/facebook/react/uimanager/util/ReactFindViewUtil; + public static final fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V + public static final fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View; + public static final fun notifyViewRendered (Landroid/view/View;)V + public static final fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V } public abstract interface class com/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java deleted file mode 100644 index ccfd1fa655a..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java +++ /dev/null @@ -1,138 +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.util; - -import android.view.View; -import android.view.ViewGroup; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.R; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** Finds views in React Native view hierarchies */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ReactFindViewUtil { - - private static final List mOnViewFoundListeners = new ArrayList<>(); - private static final Map> - mOnMultipleViewsFoundListener = new HashMap<>(); - - /** Callback to be invoked when a react native view has been found */ - public interface OnViewFoundListener { - - /** Returns the native id of the view of interest */ - String getNativeId(); - - /** - * Called when the view has been found - * - * @param view - */ - void onViewFound(View view); - } - - /** Callback to be invoked when all react native views with geiven NativeIds have been found */ - public interface OnMultipleViewsFoundListener { - - void onViewFound(View view, String nativeId); - } - - /** - * Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root} - * view hierarchy. Returns the view if found, null otherwise. - * - * @param root root of the view hierarchy from which to find the view - */ - public static @Nullable View findView(View root, String nativeId) { - String tag = getNativeId(root); - if (tag != null && tag.equals(nativeId)) { - return root; - } - - if (root instanceof ViewGroup) { - ViewGroup viewGroup = (ViewGroup) root; - for (int i = 0; i < viewGroup.getChildCount(); i++) { - View view = findView(viewGroup.getChildAt(i), nativeId); - if (view != null) { - return view; - } - } - } - - return null; - } - - /** - * Finds a view tagged with {@param onViewFoundListener}'s nativeID in the given {@param root} - * view hierarchy. If the view does not exist yet due to React Native's async layout, a listener - * will be added. When the view is found, the {@param onViewFoundListener} will be invoked. - * - * @param root root of the view hierarchy from which to find the view - */ - public static void findView(View root, OnViewFoundListener onViewFoundListener) { - View view = findView(root, onViewFoundListener.getNativeId()); - if (view != null) { - onViewFoundListener.onViewFound(view); - } - addViewListener(onViewFoundListener); - } - - /** - * Registers an OnViewFoundListener to be invoked when a view with a matching nativeID is found. - * Remove this listener using removeViewListener() if it's no longer needed. - */ - public static void addViewListener(OnViewFoundListener onViewFoundListener) { - mOnViewFoundListeners.add(onViewFoundListener); - } - - /** Removes an OnViewFoundListener previously registered with addViewListener(). */ - public static void removeViewListener(OnViewFoundListener onViewFoundListener) { - mOnViewFoundListeners.remove(onViewFoundListener); - } - - public static void addViewsListener(OnMultipleViewsFoundListener listener, Set ids) { - mOnMultipleViewsFoundListener.put(listener, ids); - } - - public static void removeViewsListener(OnMultipleViewsFoundListener listener) { - mOnMultipleViewsFoundListener.remove(listener); - } - - /** Invokes any listeners that are listening on this {@param view}'s native id */ - public static void notifyViewRendered(View view) { - String nativeId = getNativeId(view); - if (nativeId == null) { - return; - } - Iterator iterator = mOnViewFoundListeners.iterator(); - while (iterator.hasNext()) { - OnViewFoundListener listener = iterator.next(); - if (nativeId.equals(listener.getNativeId())) { - listener.onViewFound(view); - iterator.remove(); - } - } - for (Map.Entry> entry : - mOnMultipleViewsFoundListener.entrySet()) { - Set nativeIds = entry.getValue(); - if (nativeIds != null && nativeIds.contains(nativeId)) { - entry.getKey().onViewFound(view, nativeId); - } - } - } - - private static @Nullable String getNativeId(View view) { - Object tag = view.getTag(R.id.view_tag_native_id); - return tag instanceof String ? (String) tag : null; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt new file mode 100644 index 00000000000..a0a5a2112d1 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt @@ -0,0 +1,129 @@ +/* + * 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.util + +import android.view.View +import android.view.ViewGroup +import com.facebook.react.R +import java.util.ArrayList +import java.util.HashMap + +/** Finds views in React Native view hierarchies */ +public object ReactFindViewUtil { + + private val onViewFoundListeners: MutableList = ArrayList() + private val onMultipleViewsFoundListener: MutableMap> = + HashMap() + + /** Callback to be invoked when a react native view has been found */ + public interface OnViewFoundListener { + /** Returns the native id of the view of interest */ + public fun getNativeId(): String + + /** + * Called when the view has been found + * + * @param view + */ + public fun onViewFound(view: View) + } + + /** Callback to be invoked when all react native views with geiven NativeIds have been found */ + public fun interface OnMultipleViewsFoundListener { + public fun onViewFound(view: View, nativeId: String) + } + + /** + * Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root} + * view hierarchy. Returns the view if found, null otherwise. + * + * @param root root of the view hierarchy from which to find the view + */ + @JvmStatic + public fun findView(root: View, nativeId: String): View? { + if (getNativeId(root) == nativeId) { + return root + } + + if (root is ViewGroup) { + for (i in 0..): Unit { + onMultipleViewsFoundListener[listener] = ids + } + + @JvmStatic + public fun removeViewsListener(listener: OnMultipleViewsFoundListener): Unit { + onMultipleViewsFoundListener.remove(listener) + } + + /** Invokes any listeners that are listening on this {@param view}'s native id */ + @JvmStatic + public fun notifyViewRendered(view: View): Unit { + val nativeId = getNativeId(view) ?: return + val iterator = onViewFoundListeners.iterator() + while (iterator.hasNext()) { + val listener = iterator.next() + if (nativeId == listener.getNativeId()) { + listener.onViewFound(view) + iterator.remove() + } + } + onMultipleViewsFoundListener.forEach { (listener, nativeIds) -> + if (nativeId in nativeIds) { + listener.onViewFound(view, nativeId) + } + } + } + + private fun getNativeId(view: View): String? { + val tag = view.getTag(R.id.view_tag_native_id) + return tag as? String + } +}