feat(onScroll): Add `onScroll` callback for iOS & Android (#516)
* Add `onScroll` callback for iOS & Android This code was mostly extracted from https://github.com/react-native-community/react-native-webview/pull/202 I tried and tried to make it work with `Animated.event`'s `useNativeDriver`, but I was unsuccessful 😢 that'll have to be done later once I understand better how Animated's native stuff is hooked up. * fix crash for missing onScroll
This commit is contained in:
parent
409b9ae620
commit
e4c8dab2ae
|
@ -31,6 +31,9 @@ import android.webkit.WebView;
|
|||
import android.webkit.WebViewClient;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.facebook.react.views.scroll.ScrollEvent;
|
||||
import com.facebook.react.views.scroll.ScrollEventType;
|
||||
import com.facebook.react.views.scroll.OnScrollDispatchHelper;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
|
@ -446,6 +449,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
|||
}
|
||||
export.put(TopLoadingProgressEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingProgress"));
|
||||
export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest"));
|
||||
export.put(ScrollEventType.SCROLL.getJSEventName(), MapBuilder.of("registrationName", "onScroll"));
|
||||
return export;
|
||||
}
|
||||
|
||||
|
@ -780,6 +784,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
|||
protected @Nullable
|
||||
RNCWebViewClient mRNCWebViewClient;
|
||||
protected boolean sendContentSizeChangeEvents = false;
|
||||
private final OnScrollDispatchHelper mOnScrollDispatchHelper = new OnScrollDispatchHelper();
|
||||
|
||||
/**
|
||||
* WebView must be created with an context of the current activity
|
||||
|
@ -886,6 +891,26 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
|||
dispatchEvent(this, new TopMessageEvent(this.getId(), message));
|
||||
}
|
||||
|
||||
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
|
||||
super.onScrollChanged(x, y, oldX, oldY);
|
||||
|
||||
if (mOnScrollDispatchHelper.onScrollChanged(x, y)) {
|
||||
ScrollEvent event = ScrollEvent.obtain(
|
||||
this.getId(),
|
||||
ScrollEventType.SCROLL,
|
||||
x,
|
||||
y,
|
||||
mOnScrollDispatchHelper.getXFlingVelocity(),
|
||||
mOnScrollDispatchHelper.getYFlingVelocity(),
|
||||
this.computeHorizontalScrollRange(),
|
||||
this.computeVerticalScrollRange(),
|
||||
this.getWidth(),
|
||||
this.getHeight());
|
||||
|
||||
dispatchEvent(this, event);
|
||||
}
|
||||
}
|
||||
|
||||
protected void cleanupCallbacksAndDestroy() {
|
||||
setWebViewClient(null);
|
||||
destroy();
|
||||
|
|
|
@ -34,6 +34,7 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
@property (nonatomic, copy) RCTDirectEventBlock onLoadingProgress;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onMessage;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onScroll;
|
||||
@property (nonatomic, copy) WKWebView *webView;
|
||||
@end
|
||||
|
||||
|
@ -509,6 +510,30 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
if (!_scrollEnabled) {
|
||||
scrollView.bounds = _webView.bounds;
|
||||
}
|
||||
else if (_onScroll != nil) {
|
||||
NSDictionary *event = @{
|
||||
@"contentOffset": @{
|
||||
@"x": @(scrollView.contentOffset.x),
|
||||
@"y": @(scrollView.contentOffset.y)
|
||||
},
|
||||
@"contentInset": @{
|
||||
@"top": @(scrollView.contentInset.top),
|
||||
@"left": @(scrollView.contentInset.left),
|
||||
@"bottom": @(scrollView.contentInset.bottom),
|
||||
@"right": @(scrollView.contentInset.right)
|
||||
},
|
||||
@"contentSize": @{
|
||||
@"width": @(scrollView.contentSize.width),
|
||||
@"height": @(scrollView.contentSize.height)
|
||||
},
|
||||
@"layoutMeasurement": @{
|
||||
@"width": @(scrollView.frame.size.width),
|
||||
@"height": @(scrollView.frame.size.height)
|
||||
},
|
||||
@"zoomScale": @(scrollView.zoomScale ?: 1),
|
||||
};
|
||||
_onScroll(event);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDirectionalLockEnabled:(BOOL)directionalLockEnabled
|
||||
|
|
|
@ -56,6 +56,7 @@ RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL)
|
|||
*/
|
||||
RCT_EXPORT_VIEW_PROPERTY(messagingEnabled, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onMessage, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock)
|
||||
|
||||
RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)message)
|
||||
{
|
||||
|
|
|
@ -382,6 +382,7 @@ class WebView extends React.Component<IOSWebViewProps, State> {
|
|||
onLoadingProgress={this.onLoadingProgress}
|
||||
onLoadingStart={this.onLoadingStart}
|
||||
onMessage={this.onMessage}
|
||||
onScroll={this.props.onScroll}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
ref={this.webViewRef}
|
||||
scalesPageToFit={scalesPageToFit}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
NativeMethodsMixin,
|
||||
Constructor,
|
||||
UIManagerStatic,
|
||||
NativeScrollEvent,
|
||||
} from 'react-native';
|
||||
|
||||
export interface WebViewCommands {
|
||||
|
@ -213,6 +214,7 @@ export interface CommonNativeWebViewProps extends ViewProps {
|
|||
injectedJavaScript?: string;
|
||||
mediaPlaybackRequiresUserAction?: boolean;
|
||||
messagingEnabled: boolean;
|
||||
onScroll?: (event: NativeScrollEvent) => void;
|
||||
onLoadingError: (event: WebViewErrorEvent) => void;
|
||||
onLoadingFinish: (event: WebViewNavigationEvent) => void;
|
||||
onLoadingProgress: (event: WebViewProgressEvent) => void;
|
||||
|
@ -542,6 +544,11 @@ export interface WebViewSharedProps extends ViewProps {
|
|||
*/
|
||||
renderLoading?: () => ReactElement;
|
||||
|
||||
/**
|
||||
* Function that is invoked when the `WebView` scrolls.
|
||||
*/
|
||||
onScroll?: (event: NativeScrollEvent) => void;
|
||||
|
||||
/**
|
||||
* Function that is invoked when the `WebView` has finished loading.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue