diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index ce7520ee9bd..76749aaff7f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -295,6 +295,16 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec mCurrentFrameNumber++; } + @Override + public void willMountItems(UIManager uiManager) { + // noop + } + + @Override + public void didMountItems(UIManager uiManager) { + // noop + } + // For FabricUIManager only @Override @UiThread diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java index 984bcf15848..505999b3d5a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java @@ -12,10 +12,33 @@ public interface UIManagerListener { /** * Called right before view updates are dispatched at the end of a batch. This is useful if a * module needs to add UIBlocks to the queue before it is flushed. + * + *
This is called by Paper only. */ void willDispatchViewUpdates(UIManager uiManager); - /* Called right after view updates are dispatched for a frame. */ + /** + * Called on UIThread right before view updates are executed. + * + *
This is called by Fabric only. + */ + void willMountItems(UIManager uiManager); + /** + * Called on UIThread right after view updates are executed. + * + *
This is called by Fabric only. + */ + void didMountItems(UIManager uiManager); + /** + * Called on UIThread right after view updates are dispatched for a frame. Note that this will be + * called for every frame even if there are no updates. + * + *
This is called by Fabric only. + */ void didDispatchMountItems(UIManager uiManager); - /* Called right after scheduleMountItems is called in Fabric, after a new tree is committed. */ + /** + * Called right after scheduleMountItems is called in Fabric, after a new tree is committed. + * + *
This is called by Fabric only.
+ */
void didScheduleMountItems(UIManager uiManager);
}
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java
index 0da8e55dd8d..8e50e91a64d 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java
@@ -1171,6 +1171,20 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
}
private class MountItemDispatchListener implements MountItemDispatcher.ItemDispatchListener {
+ @Override
+ public void willMountItems() {
+ for (UIManagerListener listener : mListeners) {
+ listener.willMountItems(FabricUIManager.this);
+ }
+ }
+
+ @Override
+ public void didMountItems() {
+ for (UIManagerListener listener : mListeners) {
+ listener.didMountItems(FabricUIManager.this);
+ }
+ }
+
@Override
public void didDispatchMountItems() {
for (UIManagerListener listener : mListeners) {
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java
index 36abe8dd9f1..6861961c472 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java
@@ -192,6 +192,8 @@ public class MountItemDispatcher {
return false;
}
+ mItemDispatchListener.willMountItems();
+
// As an optimization, execute all ViewCommands first
// This should be:
// 1) Performant: ViewCommands are often a replacement for SetNativeProps, which we've always
@@ -298,6 +300,9 @@ public class MountItemDispatcher {
}
mBatchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime;
}
+
+ mItemDispatchListener.didMountItems();
+
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
return true;
@@ -414,6 +419,10 @@ public class MountItemDispatcher {
}
public interface ItemDispatchListener {
+ void willMountItems();
+
+ void didMountItems();
+
void didDispatchMountItems();
}
}
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java
index 6ce4d8b23d2..f76c432b590 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.uimanager.UIManagerHelper;
+import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.views.scroll.ReactScrollViewHelper.HasSmoothScroll;
import com.facebook.react.views.view.ReactViewGroup;
@@ -89,6 +90,14 @@ public class MaintainVisibleScrollPositionHelper