mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fabric: Propagation of ScrollView's contentOffset value down to ShadowNode layer on Android
Summary: This implements propagation of ScrollView's contentOffset value on Android. That allows `LayoutableShadowNode::getRelativeLayoutMetrics` (and some measure functions) return values that take that info into account. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D19027433 fbshipit-source-id: 023ff9642d023971b3d24d5cc5f7c2f4b443031e
This commit is contained in:
committed by
Facebook Github Bot
parent
c89ead313c
commit
b2f267ac3b
@@ -23,11 +23,15 @@ import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||
import com.facebook.react.views.view.ReactViewBackgroundManager;
|
||||
@@ -48,6 +52,8 @@ public class ReactScrollView extends ScrollView
|
||||
|
||||
private static @Nullable Field sScrollerField;
|
||||
private static boolean sTriedToGetScrollerField = false;
|
||||
private static final String CONTENT_OFFSET_LEFT = "contentOffsetLeft";
|
||||
private static final String CONTENT_OFFSET_TOP = "contentOffsetTop";
|
||||
|
||||
private final OnScrollDispatchHelper mOnScrollDispatchHelper = new OnScrollDispatchHelper();
|
||||
private final @Nullable OverScroller mScroller;
|
||||
@@ -74,6 +80,7 @@ public class ReactScrollView extends ScrollView
|
||||
private boolean mSnapToEnd = true;
|
||||
private View mContentView;
|
||||
private ReactViewBackgroundManager mReactBackgroundManager;
|
||||
private @Nullable StateWrapper mStateWrapper;
|
||||
|
||||
public ReactScrollView(ReactContext context) {
|
||||
this(context, null);
|
||||
@@ -287,6 +294,8 @@ public class ReactScrollView extends ScrollView
|
||||
mVelocityHelper.calculateVelocity(ev);
|
||||
int action = ev.getAction() & MotionEvent.ACTION_MASK;
|
||||
if (action == MotionEvent.ACTION_UP && mDragging) {
|
||||
updateStateOnScroll();
|
||||
|
||||
float velocityX = mVelocityHelper.getXVelocity();
|
||||
float velocityY = mVelocityHelper.getYVelocity();
|
||||
ReactScrollViewHelper.emitScrollEndDragEvent(this, velocityX, velocityY);
|
||||
@@ -488,6 +497,8 @@ public class ReactScrollView extends ScrollView
|
||||
ViewCompat.postOnAnimationDelayed(
|
||||
ReactScrollView.this, this, ReactScrollViewHelper.MOMENTUM_DELAY);
|
||||
} else {
|
||||
updateStateOnScroll();
|
||||
|
||||
if (mPagingEnabled && !mSnappingToPage) {
|
||||
// Only if we have pagingEnabled and we have not snapped to the page do we
|
||||
// need to continue checking for the scroll. And we cause that scroll by asking for
|
||||
@@ -799,4 +810,23 @@ public class ReactScrollView extends ScrollView
|
||||
public void setBorderStyle(@Nullable String style) {
|
||||
mReactBackgroundManager.setBorderStyle(style);
|
||||
}
|
||||
|
||||
public void updateState(@Nullable StateWrapper stateWrapper) {
|
||||
mStateWrapper = stateWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on any stabilized onScroll change to propagate content offset value to a Shadow Node.
|
||||
*/
|
||||
private void updateStateOnScroll() {
|
||||
if (mStateWrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
WritableMap map = new WritableNativeMap();
|
||||
map.putDouble(CONTENT_OFFSET_LEFT, PixelUtil.toDIPFromPixel(getScrollX()));
|
||||
map.putDouble(CONTENT_OFFSET_TOP, PixelUtil.toDIPFromPixel(getScrollY()));
|
||||
|
||||
mStateWrapper.updateState(map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewGroupManager;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
@@ -290,6 +292,13 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object updateState(
|
||||
ReactScrollView view, ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper) {
|
||||
view.updateState(stateWrapper);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
||||
return createExportedCustomDirectEventTypeConstants();
|
||||
|
||||
Reference in New Issue
Block a user