Skip to content

Added webview scrolling listener #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ flutterWebviewPlugin.onUrlChanged.listen((String url) {
});
```

#### Listen for scroll event in webview

```dart
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.onScrollYChanged.listen((double offsetY) { // latest offset value in vertical scroll
// compare vertical scroll changes here with old value
});

flutterWebviewPlugin.onScrollXChanged.listen((double offsetX) { // latest offset value in horizontal scroll
// compare horizontal scroll changes here with old value
});

````

Note: Do note there is a slight difference is scroll distance between ios and android. Android scroll value difference tends to be larger than ios devices.


#### Hidden WebView

```dart
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.flutter_webview_plugin;

import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;

public class ObservableWebView extends WebView {
private OnScrollChangedCallback mOnScrollChangedCallback;

public ObservableWebView(final Context context)
{
super(context);
}

public ObservableWebView(final Context context, final AttributeSet attrs)
{
super(context, attrs);
}

public ObservableWebView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
}

@Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt)
{
super.onScrollChanged(l, t, oldl, oldt);
if(mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t, oldl, oldt);
}

public OnScrollChangedCallback getOnScrollChangedCallback()
{
return mOnScrollChangedCallback;
}

public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback)
{
mOnScrollChangedCallback = onScrollChangedCallback;
}

/**
* Impliment in the activity/fragment/view that you want to listen to the webview
*/
public static interface OnScrollChangedCallback
{
public void onScroll(int l, int t, int oldl, int oldt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
}
});

observableWebView = (ObservableWebView) webView;
observableWebView.setOnScrollChangedCallback(new ObservableWebView.OnScrollChangedCallback(){
public void onScroll(int x, int y, int oldx, int oldy){
Map<String, Object> yDirection = new HashMap<>();
yDirection.put("yDirection", (double)y);
FlutterWebviewPlugin.channel.invokeMethod("onScrollYChanged", yDirection);
Map<String, Object> xDirection = new HashMap<>();
xDirection.put("xDirection", (double)x);
FlutterWebviewPlugin.channel.invokeMethod("onScrollXChanged", xDirection);
}
});

webView.setWebViewClient(webViewClient);
webView.setWebChromeClient(new WebChromeClient()
{
Expand Down
747 changes: 372 additions & 375 deletions example/ios/Flutter/flutter_assets/LICENSE

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../../../../../flutter/bin/cache/artifacts/engine/ios/Flutter.framework",
"${PODS_ROOT}/../../../../../development/flutter/bin/cache/artifacts/engine/ios/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/flutter_webview_plugin/flutter_webview_plugin.framework",
);
name = "[CP] Embed Pods Frameworks";
Expand Down
17 changes: 17 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,23 @@ class _MyHomePageState extends State<MyHomePage> {
}
});


_onScrollYChanged = flutterWebviewPlugin.onScrollYChanged.listen((double y) {
if (mounted) {
setState(() {
_history.add("Scroll in Y Direction: $y");
});
}
});

_onScrollXChanged = flutterWebviewPlugin.onScrollXChanged.listen((double x) {
if (mounted) {
setState(() {
_history.add("Scroll in X Direction: $x");
});
}
});

_onStateChanged =
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
if (mounted) {
Expand Down
11 changes: 11 additions & 0 deletions ios/Classes/FlutterWebviewPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ - (void)initWebview:(FlutterMethodCall*)call {
self.webview.scrollView.showsHorizontalScrollIndicator = [scrollBar boolValue];
self.webview.scrollView.showsVerticalScrollIndicator = [scrollBar boolValue];



_enableZoom = [withZoom boolValue];

[self.viewController.view addSubview:self.webview];
Expand All @@ -111,6 +113,14 @@ - (CGRect)parseRect:(NSDictionary *)rect {
[[rect valueForKey:@"height"] doubleValue]);
}

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
id xDirection = @{@"xDirection": @(scrollView.contentOffset.x) };
[channel invokeMethod:@"onScrollXChanged" arguments:xDirection];

id yDirection = @{@"yDirection": @(scrollView.contentOffset.y) };
[channel invokeMethod:@"onScrollYChanged" arguments:yDirection];
}

- (void)navigate:(FlutterMethodCall*)call {
if (self.webview != nil) {
NSString *url = call.arguments[@"url"];
Expand Down Expand Up @@ -213,6 +223,7 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati
}
}


- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
[channel invokeMethod:@"onState" arguments:@{@"type": @"startLoad", @"url": webView.URL.absoluteString}];
}
Expand Down
19 changes: 18 additions & 1 deletion lib/src/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class FlutterWebviewPlugin {
final _onDestroy = new StreamController<Null>.broadcast();
final _onUrlChanged = new StreamController<String>.broadcast();
final _onStateChanged = new StreamController<WebViewStateChanged>.broadcast();
final _onScrollXChanged = new StreamController<double>.broadcast();
final _onScrollYChanged = new StreamController<double>.broadcast();
final _onHttpError = new StreamController<WebViewHttpError>.broadcast();

static FlutterWebviewPlugin _instance;
Expand All @@ -37,7 +39,13 @@ class FlutterWebviewPlugin {
case 'onUrlChanged':
_onUrlChanged.add(call.arguments['url']);
break;
case 'onState':
case "onScrollXChanged":
_onScrollXChanged.add(call.arguments["xDirection"]);
break;
case "onScrollYChanged":
_onScrollYChanged.add(call.arguments["yDirection"]);
break;
case "onState":
_onStateChanged.add(
new WebViewStateChanged.fromMap(
new Map<String, dynamic>.from(call.arguments)),
Expand All @@ -61,6 +69,13 @@ class FlutterWebviewPlugin {
/// more detail than other events
Stream<WebViewStateChanged> get onStateChanged => _onStateChanged.stream;


/// Listening web view y position scroll change
Stream<double> get onScrollYChanged => _onScrollYChanged.stream;

/// Listening web view x position scroll change
Stream<double> get onScrollXChanged => _onScrollXChanged.stream;

Stream<WebViewHttpError> get onHttpError => _onHttpError.stream;

/// Start the Webview with [url]
Expand Down Expand Up @@ -172,6 +187,8 @@ class FlutterWebviewPlugin {
_onDestroy.close();
_onUrlChanged.close();
_onStateChanged.close();
_onScrollXChanged.close();
_onScrollYChanged.close();
_onHttpError.close();
_instance = null;
}
Expand Down