mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add fabric support for maintainVisibleContentPosition on Android (#35994)
Summary: Implement a few missing bits for `maintainVisibleContentPosition` to work with fabric. The main thing needed is to add 2 fabric renderer listener methods to allow to hook into specific parts of the rendering process. We need some code to execute before view updates are executed and after view updates are executed. The current methods that are exposed do not work for this case. `willDispatchViewUpdates` is called from JS thread, and there doesn't seem to be a way to add UI blocks that will be executed at the right time like we do in paper. `didDispatchMountItems` is called for every frame which we don't want and will cause lots of overhead. After that we simply need to call the right methods in the new renderer listener methods. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID] [ADDED] - Add fabric support for maintainVisibleContentPosition on Android For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> Pull Request resolved: https://github.com/facebook/react-native/pull/35994 Test Plan: Tested in RN tester maintainVisibleContentPosition example on Android with fabric enabled. Reviewed By: cipolleschi Differential Revision: D44131763 Pulled By: cortinico fbshipit-source-id: 32c0b5867d460537b18a70d472fd58052da6cf80
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8fbcfcea8d
commit
1f384f75da
+10
@@ -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
|
||||
|
||||
+25
-2
@@ -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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>This is called by Fabric only.
|
||||
*/
|
||||
void willMountItems(UIManager uiManager);
|
||||
/**
|
||||
* Called on UIThread right after view updates are executed.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>This is called by Fabric only.
|
||||
*/
|
||||
void didScheduleMountItems(UIManager uiManager);
|
||||
}
|
||||
|
||||
+14
@@ -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) {
|
||||
|
||||
+9
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -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<ScrollViewT extends ViewGroup &
|
||||
* been updated.
|
||||
*/
|
||||
public void updateScrollPosition() {
|
||||
// On Fabric this will be called internally in `didMountItems`.
|
||||
if (ViewUtil.getUIManagerType(mScrollView.getId()) == UIManagerType.FABRIC) {
|
||||
return;
|
||||
}
|
||||
updateScrollPositionInternal();
|
||||
}
|
||||
|
||||
private void updateScrollPositionInternal() {
|
||||
if (mConfig == null || mFirstVisibleView == null || mPrevFirstVisibleFrame == null) {
|
||||
return;
|
||||
}
|
||||
@@ -169,6 +178,16 @@ public class MaintainVisibleScrollPositionHelper<ScrollViewT extends ViewGroup &
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void willMountItems(UIManager uiManager) {
|
||||
computeTargetView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didMountItems(UIManager uiManager) {
|
||||
updateScrollPositionInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didDispatchMountItems(UIManager uiManager) {
|
||||
// noop
|
||||
|
||||
Reference in New Issue
Block a user