mirror of
https://github.com/status-im/react-native.git
synced 2025-01-28 02:04:55 +00:00
Add support for async callbacks in ReactFindViewUtil
Reviewed By: AaaChiuuu Differential Revision: D4841500 fbshipit-source-id: 16620d72bd636ad13085c15c38862e16da6c42d2
This commit is contained in:
parent
8fc3b48c65
commit
21819f1a99
@ -37,9 +37,28 @@ public class NativeIdTestCase extends ReactAppInstrumentationTestCase {
|
|||||||
"TextInput",
|
"TextInput",
|
||||||
"View");
|
"View");
|
||||||
|
|
||||||
|
private boolean mViewFound;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
mViewFound = false;
|
||||||
|
ReactFindViewUtil.addViewListener(new ReactFindViewUtil.OnViewFoundListener() {
|
||||||
|
@Override
|
||||||
|
public String getNativeId() {
|
||||||
|
return viewTags.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewFound(View view) {
|
||||||
|
mViewFound = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
super.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
public void testPropertyIsSetForViews() {
|
public void testPropertyIsSetForViews() {
|
||||||
for (String nativeId : viewTags) {
|
for (String nativeId : viewTags) {
|
||||||
View viewWithTag = ReactFindViewUtil.findViewByNativeId(
|
View viewWithTag = ReactFindViewUtil.findView(
|
||||||
getActivity().getRootView(),
|
getActivity().getRootView(),
|
||||||
nativeId);
|
nativeId);
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
@ -47,4 +66,28 @@ public class NativeIdTestCase extends ReactAppInstrumentationTestCase {
|
|||||||
viewWithTag);
|
viewWithTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testViewListener() {
|
||||||
|
assertTrue("OnViewFound callback was never invoked", mViewFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFindView() {
|
||||||
|
mViewFound = false;
|
||||||
|
ReactFindViewUtil.findView(
|
||||||
|
getActivity().getRootView(),
|
||||||
|
new ReactFindViewUtil.OnViewFoundListener() {
|
||||||
|
@Override
|
||||||
|
public String getNativeId() {
|
||||||
|
return viewTags.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewFound(View view) {
|
||||||
|
mViewFound = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertTrue(
|
||||||
|
"OnViewFound callback should have successfully been invoked synchronously",
|
||||||
|
mViewFound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ android_library(
|
|||||||
react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"),
|
react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"),
|
||||||
react_native_target("java/com/facebook/react/touch:touch"),
|
react_native_target("java/com/facebook/react/touch:touch"),
|
||||||
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
|
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
|
||||||
|
react_native_target("java/com/facebook/react/uimanager/util:util"),
|
||||||
react_native_target("res:uimanager"),
|
react_native_target("res:uimanager"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -5,9 +5,11 @@ package com.facebook.react.uimanager;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.facebook.react.R;
|
import com.facebook.react.R;
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
import com.facebook.react.uimanager.util.ReactFindViewUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class that should be suitable for the majority of subclasses of {@link ViewManager}.
|
* Base class that should be suitable for the majority of subclasses of {@link ViewManager}.
|
||||||
@ -96,6 +98,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|||||||
@ReactProp(name = PROP_NATIVE_ID)
|
@ReactProp(name = PROP_NATIVE_ID)
|
||||||
public void setNativeId(T view, String nativeId) {
|
public void setNativeId(T view, String nativeId) {
|
||||||
view.setTag(R.id.view_tag_native_id, nativeId);
|
view.setTag(R.id.view_tag_native_id, nativeId);
|
||||||
|
ReactFindViewUtil.notifyViewRendered(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_ACCESSIBILITY_LABEL)
|
@ReactProp(name = PROP_ACCESSIBILITY_LABEL)
|
||||||
|
@ -4,6 +4,10 @@ package com.facebook.react.uimanager.util;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
@ -14,25 +18,98 @@ import com.facebook.react.R;
|
|||||||
*/
|
*/
|
||||||
public class ReactFindViewUtil {
|
public class ReactFindViewUtil {
|
||||||
|
|
||||||
|
private static final List<OnViewFoundListener> mOnViewFoundListeners = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a view that is tagged with {@param nativeId} as its `nativeID` prop
|
* Callback to be invoked when a react native view has been found
|
||||||
*/
|
*/
|
||||||
public static @Nullable View findViewByNativeId(View view, String nativeId) {
|
public interface OnViewFoundListener {
|
||||||
Object tag = view.getTag(R.id.view_tag_native_id);
|
|
||||||
if (tag instanceof String && tag.equals(nativeId)) {
|
/**
|
||||||
return view;
|
* Returns the native id of the view of interest
|
||||||
|
*/
|
||||||
|
String getNativeId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the view has been found
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
void onViewFound(View view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view instanceof ViewGroup) {
|
/**
|
||||||
ViewGroup viewGroup = (ViewGroup) view;
|
* 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++) {
|
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
||||||
View v = findViewByNativeId(viewGroup.getChildAt(i), nativeId);
|
View view = findView(viewGroup.getChildAt(i), nativeId);
|
||||||
if (v != null) {
|
if (view != null) {
|
||||||
return v;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<OnViewFoundListener> iterator = mOnViewFoundListeners.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
OnViewFoundListener listener = iterator.next();
|
||||||
|
if (nativeId != null && nativeId.equals(listener.getNativeId())) {
|
||||||
|
listener.onViewFound(view);
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @Nullable String getNativeId(View view) {
|
||||||
|
Object tag = view.getTag(R.id.view_tag_native_id);
|
||||||
|
return tag instanceof String ? (String) tag : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user