diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js
index ccad6cefac72a9..cbe791c0d19854 100644
--- a/Libraries/Components/View/View.js
+++ b/Libraries/Components/View/View.js
@@ -259,6 +259,30 @@ const View = React.createClass({
* Used to locate this view in end-to-end tests.
*
* > This disables the 'layout-only view removal' optimization for this view!
+ *
+ * ### Android Specifics
+ *
+ * While React Native does *not* utilize XML based layouts for android Views it
+ * is still possible to add [android:id](https://developer.android.com/reference/android/view/View.html#attr_android:id)
+ * to the underlying View in order to support
+ * [findViewById](https://developer.android.com/reference/android/app/Activity.html#findViewById(int)).
+ *
+ * This is achieved by:
+ *
+ * 1. Defining a resource id in your android project's `res` folder (typically at
+ * `./android/app/src/main/res/values/ids.xml`).
+ *
+ * 2. Adding your resource ids to `ids.xml` e.g.
+ *
+ * ```xml
+ *
+ *
+ *
+ *
+ *
+ * ```
+ * 3. Using the resource id as `testID` e.g. ``.
+ *
*/
testID: PropTypes.string,
diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java
index 4e84fdab239ca3..dc0200e3cc97a6 100644
--- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java
+++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java
@@ -58,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(rootView);
mScreenshotingFrameLayout = new ScreenshotingFrameLayout(this);
- mScreenshotingFrameLayout.setId(ROOT_VIEW_ID);
+ mScreenshotingFrameLayout.setTag(ROOT_VIEW_ID);
rootView.addView(mScreenshotingFrameLayout);
mReactRootView = new ReactRootView(this);
diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java
index 8a65a51f61908d..245536fcddd96b 100644
--- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java
+++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java
@@ -29,6 +29,7 @@
import com.facebook.react.bridge.NativeModuleCallExceptionHandler;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
+import com.facebook.react.common.TestIdUtil;
import com.facebook.react.cxxbridge.CatalystInstanceImpl;
import com.facebook.react.cxxbridge.JSBundleLoader;
import com.facebook.react.cxxbridge.JSCJavaScriptExecutor;
@@ -179,37 +180,6 @@ public static T getViewAtPath(ViewGroup rootView, int... path)
* propagated into view content description.
*/
public static View getViewWithReactTestId(View rootView, String testId) {
- return findChild(rootView, hasTagValue(testId));
- }
-
- public static String getTestId(View view) {
- return view.getTag() instanceof String ? (String) view.getTag() : null;
- }
-
- private static View findChild(View root, Predicate predicate) {
- if (predicate.apply(root)) {
- return root;
- }
- if (root instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) root;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- View child = viewGroup.getChildAt(i);
- View result = findChild(child, predicate);
- if (result != null) {
- return result;
- }
- }
- }
- return null;
- }
-
- private static Predicate hasTagValue(final String tagValue) {
- return new Predicate() {
- @Override
- public boolean apply(View view) {
- Object tag = view.getTag();
- return tag != null && tag.equals(tagValue);
- }
- };
+ return rootView.findViewById(TestIdUtil.getTestId(testId));
}
}
diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/CatalystUIManagerTestCase.java b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/CatalystUIManagerTestCase.java
index f73efaf4677864..7c362e4a2d96c1 100644
--- a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/CatalystUIManagerTestCase.java
+++ b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/CatalystUIManagerTestCase.java
@@ -23,7 +23,6 @@
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
import com.facebook.react.uimanager.PixelUtil;
-import com.facebook.react.uimanager.UIImplementation;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
@@ -34,6 +33,8 @@
import com.facebook.react.testing.ReactIntegrationTestCase;
import com.facebook.react.testing.ReactTestHelper;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Test case for basic {@link UIManagerModule} functionality.
*/
@@ -102,7 +103,7 @@ public void run() {
public void testFlexUIRendered() {
FrameLayout rootView = createRootView();
- jsModule.renderFlexTestApplication(rootView.getId());
+ jsModule.renderFlexTestApplication(reactTagFor(rootView));
waitForBridgeAndUIIdle();
assertEquals(1, rootView.getChildCount());
@@ -126,7 +127,7 @@ public void testFlexUIRendered() {
// Find what could be different and make the test independent of env
// public void testFlexWithTextViews() {
// FrameLayout rootView = createRootView();
- // jsModule.renderFlexWithTextApplication(rootView.getId());
+ // jsModule.renderFlexWithTextApplication(reactTagFor(rootView));
// waitForBridgeAndUIIdle();
//
// assertEquals(1, rootView.getChildCount());
@@ -164,7 +165,7 @@ public void testFlexUIRendered() {
public void testAbsolutePositionUIRendered() {
FrameLayout rootView = createRootView();
- jsModule.renderAbsolutePositionTestApplication(rootView.getId());
+ jsModule.renderAbsolutePositionTestApplication(reactTagFor(rootView));
waitForBridgeAndUIIdle();
assertEquals(1, rootView.getChildCount());
@@ -178,7 +179,7 @@ public void testAbsolutePositionUIRendered() {
public void testUpdatePositionInList() {
FrameLayout rootView = createRootView();
- jsModule.renderUpdatePositionInListTestApplication(rootView.getId());
+ jsModule.renderUpdatePositionInListTestApplication(reactTagFor(rootView));
waitForBridgeAndUIIdle();
ViewGroup containerView = getViewByTestId(rootView, "container");
@@ -207,7 +208,7 @@ public void testUpdatePositionInList() {
public void testAbsolutePositionBottomRightUIRendered() {
FrameLayout rootView = createRootView();
- jsModule.renderAbsolutePositionBottomRightTestApplication(rootView.getId());
+ jsModule.renderAbsolutePositionBottomRightTestApplication(reactTagFor(rootView));
waitForBridgeAndUIIdle();
assertEquals(1, rootView.getChildCount());
diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/TextInputTestCase.java b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/TextInputTestCase.java
index 40aa97813554a2..20e2a73d93c901 100644
--- a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/TextInputTestCase.java
+++ b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/TextInputTestCase.java
@@ -25,6 +25,8 @@
import com.facebook.react.views.textinput.ReactTextChangedEvent;
import com.facebook.react.views.textinput.ReactTextInputEvent;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Test to verify that TextInput renders correctly
*/
@@ -114,7 +116,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
@@ -122,7 +124,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
newText.toString(),
"",
start,
@@ -146,7 +148,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
@@ -154,7 +156,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
moreText,
"",
start,
@@ -178,7 +180,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
@@ -186,7 +188,7 @@ public void testMetionsInputColors() throws Throwable {
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
- reactEditText.getId(),
+ reactTagFor(reactEditText),
moreText,
"",
start,
diff --git a/ReactAndroid/src/main/java/com/facebook/react/XReactInstanceManagerImpl.java b/ReactAndroid/src/main/java/com/facebook/react/XReactInstanceManagerImpl.java
index 2a396cb09f2055..85b280b5c2090c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/XReactInstanceManagerImpl.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/XReactInstanceManagerImpl.java
@@ -88,6 +88,7 @@
import static com.facebook.react.bridge.ReactMarkerConstants.PROCESS_PACKAGES_START;
import static com.facebook.react.bridge.ReactMarkerConstants.SETUP_REACT_CONTEXT_END;
import static com.facebook.react.bridge.ReactMarkerConstants.SETUP_REACT_CONTEXT_START;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
/**
@@ -797,7 +798,7 @@ private void attachMeasuredRootViewToInstance(
// Reset view content as it's going to be populated by the application content from JS
rootView.removeAllViews();
- rootView.setId(View.NO_ID);
+ rootView.setTag(View.NO_ID);
UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
int rootTag = uiManagerModule.addMeasuredRootView(rootView);
@@ -818,7 +819,7 @@ private void detachViewFromInstance(
CatalystInstance catalystInstance) {
UiThreadUtil.assertOnUiThread();
catalystInstance.getJSModule(AppRegistry.class)
- .unmountApplicationComponentAtRootTag(rootView.getId());
+ .unmountApplicationComponentAtRootTag(reactTagFor(rootView));
}
private void tearDownReactContext(ReactContext reactContext) {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/TestIdUtil.java b/ReactAndroid/src/main/java/com/facebook/react/common/TestIdUtil.java
new file mode 100644
index 00000000000000..38b8010b4fcfc9
--- /dev/null
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/TestIdUtil.java
@@ -0,0 +1,55 @@
+package com.facebook.react.common;
+
+import android.view.View;
+
+import com.facebook.react.common.annotations.VisibleForTesting;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class TestIdUtil {
+ private static final ConcurrentHashMap mTestIds = new ConcurrentHashMap<>();
+ // Integer values in R.class are typically large. To avoid colliding with R.class we
+ // use smaller values for ids when no resource id exists.
+ private static final int mStartingInternalId = 1;
+ private static final AtomicInteger mInternalId = new AtomicInteger(mStartingInternalId);
+
+ /**
+ * Looks for defined resource IDs in R.class by the name of testId and if a matching resource ID is
+ * found it is passed to the view's setId method. If the given testId cannot be found in R.class,
+ * an increment value is assigned instead.
+ */
+ public static void setTestId(T view, String testId) {
+ int mappedTestId;
+ if (!mTestIds.containsKey(testId)) {
+ mappedTestId = view.getResources().getIdentifier(testId, "id", view.getContext().getPackageName());
+ final boolean idNotFoundInResources = mappedTestId <= 0;
+ if (idNotFoundInResources) {
+ mappedTestId = mInternalId.getAndIncrement();
+ }
+ mTestIds.put(testId, mappedTestId);
+ } else {
+ mappedTestId = mTestIds.get(testId);
+ }
+
+ if (mappedTestId != 0 && view.getId() != mappedTestId) {
+ view.setId(mappedTestId);
+ }
+ }
+
+ /**
+ * Used for e2e tests that do not yet have testIDs stored in ids.xml. It is strongly
+ * advised that you reference ids that have been generated in R.class to avoid collisions and
+ * to properly support UIAutomatorViewer.
+ */
+ @VisibleForTesting
+ public static int getTestId(String testId) {
+ return mTestIds.containsKey(testId) ? mTestIds.get(testId) : View.NO_ID;
+ }
+
+ @VisibleForTesting
+ public static void resetStateInTest() {
+ mTestIds.clear();
+ mInternalId.set(mStartingInternalId);
+ }
+}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/ViewMethodsUtil.java b/ReactAndroid/src/main/java/com/facebook/react/common/ViewMethodsUtil.java
new file mode 100644
index 00000000000000..24f4794bbc1392
--- /dev/null
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/ViewMethodsUtil.java
@@ -0,0 +1,16 @@
+package com.facebook.react.common;
+
+import android.view.View;
+
+public class ViewMethodsUtil {
+
+ /**
+ * Returns the react tag for the view. If no react tag has been set then {@link View#NO_ID} is
+ * returned.
+ */
+ public static int reactTagFor(View view) {
+ return view == null || view.getTag() == null ?
+ View.NO_ID :
+ (int) view.getTag();
+ }
+}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK b/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK
index 44cea8fdce54f4..fa495f2e5afa5b 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK
+++ b/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK
@@ -6,6 +6,7 @@ android_library(
deps = [
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
+ react_native_target('java/com/facebook/react/common:common'),
],
visibility = [
'PUBLIC'
diff --git a/ReactAndroid/src/main/java/com/facebook/react/touch/JSResponderHandler.java b/ReactAndroid/src/main/java/com/facebook/react/touch/JSResponderHandler.java
index 7140e2c303fea8..72f0f3cc0c35ce 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/touch/JSResponderHandler.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/touch/JSResponderHandler.java
@@ -15,6 +15,8 @@
import android.view.ViewGroup;
import android.view.ViewParent;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* This class coordinates JSResponder commands for {@link UIManagerModule}. It should be set as
* OnInterceptTouchEventListener for all newly created native views that implements
@@ -70,7 +72,7 @@ public boolean onInterceptTouchEvent(ViewGroup v, MotionEvent event) {
// Therefore since "UP" event is the last event in a gesture, we should just let it reach the
// original target that is a child view of {@param v}.
// http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)
- return v.getId() == currentJSResponder;
+ return reactTagFor(v) == currentJSResponder;
}
return false;
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java
index 815bad0faddcc5..02accaf536ecfa 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java
@@ -5,9 +5,9 @@
import android.graphics.Color;
import android.os.Build;
import android.view.View;
-import android.view.ViewGroup;
import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.common.TestIdUtil;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
@@ -84,7 +84,7 @@ public void setRenderToHardwareTexture(T view, boolean useHWTexture) {
@ReactProp(name = PROP_TEST_ID)
public void setTestId(T view, String testId) {
- view.setTag(testId);
+ TestIdUtil.setTestId(view, testId);
}
@ReactProp(name = PROP_ACCESSIBILITY_LABEL)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java
index a5b157d0f1029f..4b64dde817a2ca 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java
@@ -31,6 +31,7 @@
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
+import com.facebook.react.common.ViewMethodsUtil;
import com.facebook.react.touch.JSResponderHandler;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener;
@@ -40,6 +41,8 @@
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Delegate of {@link UIManagerModule} that owns the native view hierarchy and mapping between
* native view names used in JS and corresponding instances of {@link ViewManager}. The
@@ -200,6 +203,14 @@ private void updateLayout(View viewToUpdate, int x, int y, int width, int height
}
}
+ /**
+ * Creates a view and adds it to a corresponding {@link ViewManager}.
+ *
+ * The tag (a.k.a. React Tag) is stored with {@link View#setTag(Object)}. It is necessary to use
+ * {@link ViewMethodsUtil#reactTagFor(View)} wherever the original
+ * tag is needed e.g. when communicating with the Shadow DOM or with JS about a particular react
+ * tag.
+ */
public void createView(
ThemedReactContext themedContext,
int tag,
@@ -219,10 +230,10 @@ public void createView(
mTagsToViews.put(tag, view);
mTagsToViewManagers.put(tag, viewManager);
- // Use android View id field to store React tag. This is possible since we don't inflate
+ // Use android View tag field to store React tag. This is possible since we don't inflate
// React views from layout xmls. Thus it is easier to just reuse that field instead of
// creating another (potentially much more expensive) mapping from view to React tag
- view.setId(tag);
+ view.setTag(tag);
if (initialProps != null) {
viewManager.updateProperties(view, initialProps);
}
@@ -240,13 +251,13 @@ private static String constructManageChildrenErrorMessage(
StringBuilder stringBuilder = new StringBuilder();
if (null != viewToManage) {
- stringBuilder.append("View tag:" + viewToManage.getId() + "\n");
+ stringBuilder.append("View tag:" + reactTagFor(viewToManage) + "\n");
stringBuilder.append(" children(" + viewManager.getChildCount(viewToManage) + "): [\n");
for (int index=0; index= 0; i--) {
View child = viewGroupManager.getChildAt(viewGroup, i);
- if (mTagsToViews.get(child.getId()) != null) {
+ if (mTagsToViews.get(reactTagFor(child)) != null) {
dropView(child);
}
}
viewGroupManager.removeAllViews(viewGroup);
}
- mTagsToViews.remove(view.getId());
- mTagsToViewManagers.remove(view.getId());
+ mTagsToViews.remove(reactTag);
+ mTagsToViewManagers.remove(reactTag);
}
public void removeRootView(int rootViewTag) {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java
index 4ef74fafc941f5..9662ba295d3260 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java
@@ -22,6 +22,8 @@
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.touch.ReactHitSlopView;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Class responsible for identifying which react view should handle a given {@link MotionEvent}.
* It uses the event coordinates to traverse the view hierarchy and return a suitable view.
@@ -87,7 +89,7 @@ public static int findTargetTagAndCoordinatesForTouch(
float[] viewCoords,
@Nullable int[] nativeViewTag) {
UiThreadUtil.assertOnUiThread();
- int targetTag = viewGroup.getId();
+ int targetTag = reactTagFor(viewGroup);
// Store eventCoords in array so that they are modified to be relative to the targetView found.
viewCoords[0] = eventX;
viewCoords[1] = eventY;
@@ -96,7 +98,7 @@ public static int findTargetTagAndCoordinatesForTouch(
View reactTargetView = findClosestReactAncestor(nativeTargetView);
if (reactTargetView != null) {
if (nativeViewTag != null) {
- nativeViewTag[0] = reactTargetView.getId();
+ nativeViewTag[0] = reactTagFor(reactTargetView);
}
targetTag = getTouchTargetForView(reactTargetView, viewCoords[0], viewCoords[1]);
}
@@ -105,7 +107,7 @@ public static int findTargetTagAndCoordinatesForTouch(
}
private static View findClosestReactAncestor(View view) {
- while (view != null && view.getId() <= 0) {
+ while (view != null && reactTagFor(view) <= 0) {
view = (View) view.getParent();
}
return view;
@@ -224,7 +226,7 @@ private static boolean isTransformedTouchPointInView(
// ViewGroup).
if (view instanceof ReactCompoundView) {
int reactTag = ((ReactCompoundView)view).reactTagForTouch(eventCoords[0], eventCoords[1]);
- if (reactTag != view.getId()) {
+ if (reactTag != reactTagFor(view)) {
// make sure we exclude the View itself because of the PointerEvents.BOX_NONE
return view;
}
@@ -256,7 +258,7 @@ private static int getTouchTargetForView(View targetView, float eventX, float ev
// {@link #findTouchTargetView()}.
return ((ReactCompoundView) targetView).reactTagForTouch(eventX, eventY);
}
- return targetView.getId();
+ return reactTagFor(targetView);
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java
index e61d1266e1f29e..05e88008ddf134 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java
@@ -36,6 +36,8 @@
import com.facebook.react.views.drawer.events.DrawerSlideEvent;
import com.facebook.react.views.drawer.events.DrawerStateChangedEvent;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* View Manager for {@link ReactDrawerLayout} components.
*/
@@ -187,25 +189,25 @@ public DrawerEventEmitter(DrawerLayout drawerLayout, EventDispatcher eventDispat
@Override
public void onDrawerSlide(View view, float v) {
mEventDispatcher.dispatchEvent(
- new DrawerSlideEvent(mDrawerLayout.getId(), v));
+ new DrawerSlideEvent(reactTagFor(mDrawerLayout), v));
}
@Override
public void onDrawerOpened(View view) {
mEventDispatcher.dispatchEvent(
- new DrawerOpenedEvent(mDrawerLayout.getId()));
+ new DrawerOpenedEvent(reactTagFor(mDrawerLayout)));
}
@Override
public void onDrawerClosed(View view) {
mEventDispatcher.dispatchEvent(
- new DrawerClosedEvent(mDrawerLayout.getId()));
+ new DrawerClosedEvent(reactTagFor(mDrawerLayout)));
}
@Override
public void onDrawerStateChanged(int i) {
mEventDispatcher.dispatchEvent(
- new DrawerStateChangedEvent(mDrawerLayout.getId(), i));
+ new DrawerStateChangedEvent(reactTagFor(mDrawerLayout), i));
}
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java
index f519627b634f1c..62b045d5f72dfb 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java
@@ -59,6 +59,8 @@
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Wrapper class around Fresco's GenericDraweeView, enabling persisting props across multiple view
* update and consistent processing of both static and network images.
@@ -192,7 +194,7 @@ public void setShouldNotifyLoadEvents(boolean shouldNotify) {
@Override
public void onSubmit(String id, Object callerContext) {
mEventDispatcher.dispatchEvent(
- new ImageLoadEvent(getId(), ImageLoadEvent.ON_LOAD_START));
+ new ImageLoadEvent(getReactTag(), ImageLoadEvent.ON_LOAD_START));
}
@Override
@@ -202,19 +204,19 @@ public void onFinalImageSet(
@Nullable Animatable animatable) {
if (imageInfo != null) {
mEventDispatcher.dispatchEvent(
- new ImageLoadEvent(getId(), ImageLoadEvent.ON_LOAD,
+ new ImageLoadEvent(getReactTag(), ImageLoadEvent.ON_LOAD,
mImageSource.getSource(), imageInfo.getWidth(), imageInfo.getHeight()));
mEventDispatcher.dispatchEvent(
- new ImageLoadEvent(getId(), ImageLoadEvent.ON_LOAD_END));
+ new ImageLoadEvent(getReactTag(), ImageLoadEvent.ON_LOAD_END));
}
}
@Override
public void onFailure(String id, Throwable throwable) {
mEventDispatcher.dispatchEvent(
- new ImageLoadEvent(getId(), ImageLoadEvent.ON_ERROR));
+ new ImageLoadEvent(getReactTag(), ImageLoadEvent.ON_ERROR));
mEventDispatcher.dispatchEvent(
- new ImageLoadEvent(getId(), ImageLoadEvent.ON_LOAD_END));
+ new ImageLoadEvent(getReactTag(), ImageLoadEvent.ON_LOAD_END));
}
};
}
@@ -222,6 +224,10 @@ public void onFailure(String id, Throwable throwable) {
mIsDirty = true;
}
+ private int getReactTag() {
+ return reactTagFor(this);
+ }
+
public void setBorderColor(int borderColor) {
mBorderColor = borderColor;
mIsDirty = true;
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java
index 220284ef3dd870..113701e3dfa5c0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java
@@ -22,6 +22,8 @@
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* View manager for {@link ReactModalHostView} components.
*/
@@ -76,14 +78,14 @@ protected void addEventEmitters(
new ReactModalHostView.OnRequestCloseListener() {
@Override
public void onRequestClose(DialogInterface dialog) {
- dispatcher.dispatchEvent(new RequestCloseEvent(view.getId()));
+ dispatcher.dispatchEvent(new RequestCloseEvent(reactTagFor(view)));
}
});
view.setOnShowListener(
new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
- dispatcher.dispatchEvent(new ShowEvent(view.getId()));
+ dispatcher.dispatchEvent(new ShowEvent(reactTagFor(view)));
}
});
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
index c2a5c933dbec4c..54b2a3978ab943 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
@@ -36,6 +36,8 @@
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.view.ReactViewGroup;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
*
@@ -299,7 +301,7 @@ protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
@Override
public void run() {
((ReactContext) getContext()).getNativeModule(UIManagerModule.class)
- .updateNodeSize(getChildAt(0).getId(), w, h);
+ .updateNodeSize(reactTagFor(getChildAt(0)), w, h);
}
});
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java
index 5e1e9ccf33a236..a6d2af492c3dce 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java
@@ -30,6 +30,8 @@
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.picker.events.PickerItemSelectEvent;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* {@link ViewManager} for the {@link ReactPicker} view. This is abstract because the
* {@link Spinner} doesn't support setting the mode (dropdown/dialog) outside the constructor, so
@@ -156,7 +158,7 @@ public PickerEventEmitter(ReactPicker reactPicker, EventDispatcher eventDispatch
@Override
public void onItemSelected(int position) {
mEventDispatcher.dispatchEvent( new PickerItemSelectEvent(
- mReactPicker.getId(), position));
+ reactTagFor(mReactPicker), position));
}
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/recyclerview/RecyclerViewBackedScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/recyclerview/RecyclerViewBackedScrollView.java
index d823ac88bf3938..d96aaf72ef0c62 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/recyclerview/RecyclerViewBackedScrollView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/recyclerview/RecyclerViewBackedScrollView.java
@@ -15,12 +15,15 @@
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.annotations.VisibleForTesting;
+import com.facebook.react.uimanager.NativeViewHierarchyManager;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
import com.facebook.react.uimanager.events.NativeGestureUtil;
import com.facebook.react.views.scroll.ScrollEvent;
import com.facebook.react.views.scroll.ScrollEventType;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Wraps {@link RecyclerView} providing interface similar to `ScrollView.js` where each children
* will be rendered as a separate {@link RecyclerView} row.
@@ -294,7 +297,7 @@ public int getItemCount() {
@Override
public long getItemId(int position) {
- return mViews.get(position).getId();
+ return reactTagFor(mViews.get(position));
}
public View getView(int index) {
@@ -342,7 +345,7 @@ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
((ReactContext) getContext()).getNativeModule(UIManagerModule.class).getEventDispatcher()
.dispatchEvent(ScrollEvent.obtain(
- getId(),
+ reactTagFor(this),
ScrollEventType.SCROLL,
0, /* offsetX = 0, horizontal scrolling only */
calculateAbsoluteOffset(),
@@ -356,7 +359,7 @@ private void onTotalChildrenHeightChange(int newTotalChildrenHeight) {
if (mSendContentSizeChangeEvents) {
((ReactContext) getContext()).getNativeModule(UIManagerModule.class).getEventDispatcher()
.dispatchEvent(new ContentSizeChangeEvent(
- getId(),
+ reactTagFor(this),
getWidth(),
newTotalChildrenHeight));
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java
index 966c50bb30a797..5f955a0d9e2de2 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java
@@ -15,6 +15,8 @@
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.UIManagerModule;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Helper class that deals with emitting Scroll Events.
*/
@@ -55,7 +57,7 @@ private static void emitScrollEvent(ViewGroup scrollView, ScrollEventType scroll
ReactContext reactContext = (ReactContext) scrollView.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
ScrollEvent.obtain(
- scrollView.getId(),
+ reactTagFor(scrollView),
scrollEventType,
scrollView.getScrollX(),
scrollView.getScrollY(),
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java
index 87f930ab46db97..61df272940ee83 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java
@@ -27,6 +27,8 @@
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Manages instances of {@code ReactSlider}.
*
@@ -79,7 +81,7 @@ public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
new ReactSliderEvent(
- seekbar.getId(),
+ reactTagFor(seekbar),
((ReactSlider)seekbar).toRealProgress(progress),
fromUser));
}
@@ -93,7 +95,7 @@ public void onStopTrackingTouch(SeekBar seekbar) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
new ReactSlidingCompleteEvent(
- seekbar.getId(),
+ reactTagFor(seekbar),
((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())));
}
};
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java
index 99b62b4a96b67e..ae815bb08a5680 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java
@@ -27,6 +27,7 @@
import com.facebook.react.uimanager.annotations.ReactProp;
import static com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager.REACT_CLASS;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
/**
* ViewManager for {@link ReactSwipeRefreshLayout} which allows the user to "pull to refresh" a
@@ -94,7 +95,7 @@ protected void addEventEmitters(
@Override
public void onRefresh() {
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher()
- .dispatchEvent(new RefreshEvent(view.getId()));
+ .dispatchEvent(new RefreshEvent(reactTagFor(view)));
}
});
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java
index d05f8bae33fd3f..8f52ca107de078 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java
@@ -25,6 +25,8 @@
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* View manager for {@link ReactSwitch} components.
*/
@@ -76,7 +78,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ReactContext reactContext = (ReactContext) buttonView.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
new ReactSwitchEvent(
- buttonView.getId(),
+ reactTagFor(buttonView),
isChecked));
}
};
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
index 50828a80ba6818..29d63f54d50379 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
@@ -26,6 +26,8 @@
import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
public class ReactTextView extends TextView implements ReactCompoundView {
private static final ViewGroup.LayoutParams EMPTY_LAYOUT_PARAMS =
@@ -74,7 +76,7 @@ public void setText(ReactTextUpdate update) {
@Override
public int reactTagForTouch(float touchX, float touchY) {
Spanned text = (Spanned) getText();
- int target = getId();
+ int target = reactTagFor(this);
int x = (int) touchX;
int y = (int) touchY;
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
index 2a2cf446c70de9..dd510419b8ac44 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
@@ -50,9 +50,10 @@
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.facebook.react.views.text.DefaultStyleValuesUtil;
import com.facebook.react.views.text.ReactTextUpdate;
-import com.facebook.react.views.text.ReactTextView;
import com.facebook.react.views.text.TextInlineImageSpan;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Manages instances of TextInput.
*/
@@ -645,7 +646,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO: t7936714 merge these events
mEventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
- mEditText.getId(),
+ reactTagFor(mEditText),
s.toString(),
PixelUtil.toDIPFromPixel(contentWidth),
PixelUtil.toDIPFromPixel(contentHeight),
@@ -653,7 +654,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
mEventDispatcher.dispatchEvent(
new ReactTextInputEvent(
- mEditText.getId(),
+ reactTagFor(mEditText),
newText,
oldText,
start,
@@ -678,15 +679,15 @@ public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
eventDispatcher.dispatchEvent(
new ReactTextInputFocusEvent(
- editText.getId()));
+ reactTagFor(editText)));
} else {
eventDispatcher.dispatchEvent(
new ReactTextInputBlurEvent(
- editText.getId()));
+ reactTagFor(editText)));
eventDispatcher.dispatchEvent(
new ReactTextInputEndEditingEvent(
- editText.getId(),
+ reactTagFor(editText),
editText.getText().toString()));
}
}
@@ -703,7 +704,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent keyEvent) {
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(
new ReactTextInputSubmitEditingEvent(
- editText.getId(),
+ reactTagFor(editText),
editText.getText().toString()));
}
if (actionId == EditorInfo.IME_ACTION_NEXT ||
@@ -749,7 +750,7 @@ public void onLayout() {
mEventDispatcher.dispatchEvent(
new ReactContentSizeChangedEvent(
- mEditText.getId(),
+ reactTagFor(mEditText),
PixelUtil.toDIPFromPixel(contentWidth),
PixelUtil.toDIPFromPixel(contentHeight)));
}
@@ -777,7 +778,7 @@ public void onSelectionChanged(int start, int end) {
if (mPreviousSelectionStart != start || mPreviousSelectionEnd != end) {
mEventDispatcher.dispatchEvent(
new ReactTextInputSelectionEvent(
- mReactEditText.getId(),
+ reactTagFor(mReactEditText),
start,
end
));
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbarManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbarManager.java
index b37040a22f3ed8..264bfb0bb6ea8f 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbarManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbarManager.java
@@ -33,6 +33,8 @@
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.toolbar.events.ToolbarClickEvent;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Manages instances of ReactToolbar.
*/
@@ -130,7 +132,7 @@ protected void addEventEmitters(final ThemedReactContext reactContext, final Rea
@Override
public void onClick(View v) {
mEventDispatcher.dispatchEvent(
- new ToolbarClickEvent(view.getId(), -1));
+ new ToolbarClickEvent(reactTagFor(view), -1));
}
});
@@ -140,7 +142,7 @@ public void onClick(View v) {
public boolean onMenuItemClick(MenuItem menuItem) {
mEventDispatcher.dispatchEvent(
new ToolbarClickEvent(
- view.getId(),
+ reactTagFor(view),
menuItem.getOrder()));
return true;
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java
index c5a2ea12f71557..e542cdc6aea543 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java
@@ -23,6 +23,8 @@
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.NativeGestureUtil;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Wrapper view for {@link ViewPager}. It's forwarding calls to {@link ViewGroup#addView} to add
* views to custom {@link PagerAdapter} instance which is used by {@link NativeViewHierarchyManager}
@@ -123,14 +125,14 @@ private class PageChangeListener implements OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mEventDispatcher.dispatchEvent(
- new PageScrollEvent(getId(), position, positionOffset));
+ new PageScrollEvent(getReactTag(), position, positionOffset));
}
@Override
public void onPageSelected(int position) {
if (!mIsCurrentItemFromJs) {
mEventDispatcher.dispatchEvent(
- new PageSelectedEvent(getId(), position));
+ new PageSelectedEvent(getReactTag(), position));
}
}
@@ -151,10 +153,14 @@ public void onPageScrollStateChanged(int state) {
throw new IllegalStateException("Unsupported pageScrollState");
}
mEventDispatcher.dispatchEvent(
- new PageScrollStateChangedEvent(getId(), pageScrollState));
+ new PageScrollStateChangedEvent(getReactTag(), pageScrollState));
}
}
+ private int getReactTag() {
+ return reactTagFor(this);
+ }
+
private final EventDispatcher mEventDispatcher;
private boolean mIsCurrentItemFromJs;
private boolean mScrollEnabled = true;
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
index 20951b621291fe..bd8475c7e3157d 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
@@ -57,6 +57,8 @@
import org.json.JSONObject;
import org.json.JSONException;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
+
/**
* Manages instances of {@link WebView}
*
@@ -126,7 +128,7 @@ public void onPageStarted(WebView webView, String url, Bitmap favicon) {
dispatchEvent(
webView,
new TopLoadingStartEvent(
- webView.getId(),
+ reactTagFor(webView),
createWebViewEvent(webView, url)));
}
@@ -162,7 +164,7 @@ public void onReceivedError(
dispatchEvent(
webView,
- new TopLoadingErrorEvent(webView.getId(), eventData));
+ new TopLoadingErrorEvent(reactTagFor(webView), eventData));
}
@Override
@@ -172,7 +174,7 @@ public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload
dispatchEvent(
webView,
new TopLoadingStartEvent(
- webView.getId(),
+ reactTagFor(webView),
createWebViewEvent(webView, url)));
}
@@ -180,13 +182,13 @@ private void emitFinishEvent(WebView webView, String url) {
dispatchEvent(
webView,
new TopLoadingFinishEvent(
- webView.getId(),
+ reactTagFor(webView),
createWebViewEvent(webView, url)));
}
private WritableMap createWebViewEvent(WebView webView, String url) {
WritableMap event = Arguments.createMap();
- event.putDouble("target", webView.getId());
+ event.putDouble("target", reactTagFor(webView));
// Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks
// like onPageFinished
event.putString("url", url);
@@ -512,7 +514,7 @@ public void onNewPicture(WebView webView, Picture picture) {
dispatchEvent(
webView,
new ContentSizeChangeEvent(
- webView.getId(),
+ reactTagFor(webView),
webView.getWidth(),
webView.getContentHeight()));
}
diff --git a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java
index 3bcdab6acdd5cb..a66c858dbbf30d 100644
--- a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java
+++ b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java
@@ -112,7 +112,7 @@ public void testTouchEmitter() {
int rootViewId = 7;
ReactRootView rootView = new ReactRootView(mReactContext);
- rootView.setId(rootViewId);
+ rootView.setTag(rootViewId);
rootView.startReactApplication(instanceManager, "");
rootView.simulateAttachForTesting();
diff --git a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java
index 9f4db9d6fd1945..95c3726e3ea6a6 100644
--- a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java
+++ b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java
@@ -9,6 +9,8 @@
package com.facebook.react.animated;
+import android.view.View;
+
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JavaOnlyArray;
@@ -27,6 +29,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
@@ -35,6 +39,7 @@
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
+import static com.facebook.react.common.ViewMethodsUtil.reactTagFor;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
@@ -45,6 +50,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
/**
* Tests the animated nodes graph traversal algorithm from {@link NativeAnimatedNodesManager}.
@@ -54,6 +60,9 @@
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
public class NativeAnimatedNodeTraversalTest {
+ @Mock
+ private View view;
+ private final int viewTag = 1000;
private static long FRAME_LEN_NANOS = 1000000000L / 60L;
private static long INITIAL_FRAME_TIME_NANOS = 14599233201256L; /* random */
@@ -72,6 +81,8 @@ private long nextFrameTime() {
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(reactTagFor(view)).thenReturn(viewTag);
PowerMockito.mockStatic(Arguments.class);
PowerMockito.when(Arguments.createArray()).thenAnswer(new Answer