Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit eca290f

Browse files
author
TheVinhLuong
committed
Implement scroll listener for Android
1 parent b108c79 commit eca290f

File tree

17 files changed

+1855
-2446
lines changed

17 files changed

+1855
-2446
lines changed

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java

Lines changed: 1164 additions & 1505 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package io.flutter.plugins.webviewflutter;
2+
3+
4+
public interface OnScrollChangedCallback {
5+
void onScroll(int l, int t, int oldl, int oldt);
6+
}

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private void setUp(
8181

8282
webViewHostApi =
8383
new WebViewHostApiImpl(
84-
instanceManager, new WebViewHostApiImpl.WebViewProxy(), context, containerView);
84+
instanceManager, new WebViewHostApiImpl.WebViewProxy(), context, containerView,new WebViewClientFlutterApiImpl(binaryMessenger, instanceManager));
8585
javaScriptChannelHostApi =
8686
new JavaScriptChannelHostApiImpl(
8787
instanceManager,

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,17 @@
1212
import android.webkit.WebChromeClient;
1313
import android.webkit.WebView;
1414
import android.webkit.WebViewClient;
15+
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
1519
import androidx.annotation.NonNull;
1620
import androidx.annotation.Nullable;
1721
import io.flutter.plugin.platform.PlatformView;
1822
import io.flutter.plugins.webviewflutter.DownloadListenerHostApiImpl.DownloadListenerImpl;
1923
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewHostApi;
2024
import io.flutter.plugins.webviewflutter.WebChromeClientHostApiImpl.WebChromeClientImpl;
2125
import io.flutter.plugins.webviewflutter.WebViewClientHostApiImpl.ReleasableWebViewClient;
22-
import java.util.HashMap;
23-
import java.util.Map;
2426

2527
/**
2628
* Host api implementation for {@link WebView}.
@@ -35,8 +37,10 @@ public class WebViewHostApiImpl implements WebViewHostApi {
3537

3638
private final InstanceManager instanceManager;
3739
private final WebViewProxy webViewProxy;
40+
private final WebViewClientFlutterApiImpl flutterApi;
3841
// Only used with WebView using virtual displays.
39-
@Nullable private final View containerView;
42+
@Nullable
43+
private final View containerView;
4044

4145
private Context context;
4246

@@ -111,6 +115,7 @@ public static class WebViewPlatformView extends WebView implements PlatformView,
111115
new ReleasableValue<>();
112116
private final Map<String, ReleasableValue<JavaScriptChannel>> javaScriptInterfaces =
113117
new HashMap<>();
118+
private OnScrollChangedCallback mOnScrollChangedCallback;
114119

115120
/**
116121
* Creates a {@link WebViewPlatformView}.
@@ -185,6 +190,18 @@ public void release() {
185190
}
186191
javaScriptInterfaces.clear();
187192
}
193+
194+
@Override
195+
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
196+
super.onScrollChanged(l, t, oldl, oldt);
197+
if (mOnScrollChangedCallback != null) {
198+
mOnScrollChangedCallback.onScroll(l, t, oldl, oldt);
199+
}
200+
}
201+
202+
public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) {
203+
mOnScrollChangedCallback = onScrollChangedCallback;
204+
}
188205
}
189206

190207
/**
@@ -303,19 +320,21 @@ public void release() {
303320
* Creates a host API that handles creating {@link WebView}s and invoking its methods.
304321
*
305322
* @param instanceManager maintains instances stored to communicate with Dart objects
306-
* @param webViewProxy handles creating {@link WebView}s and calling its static methods
307-
* @param context an Activity Context to access application assets. This value cannot be null.
308-
* @param containerView parent of the webView
323+
* @param webViewProxy handles creating {@link WebView}s and calling its static methods
324+
* @param context an Activity Context to access application assets. This value cannot be null.
325+
* @param containerView parent of the webView
309326
*/
310327
public WebViewHostApiImpl(
311-
InstanceManager instanceManager,
312-
WebViewProxy webViewProxy,
313-
Context context,
314-
@Nullable View containerView) {
328+
InstanceManager instanceManager,
329+
WebViewProxy webViewProxy,
330+
Context context,
331+
@Nullable View containerView,
332+
WebViewClientFlutterApiImpl flutterApi) {
315333
this.instanceManager = instanceManager;
316334
this.webViewProxy = webViewProxy;
317335
this.context = context;
318336
this.containerView = containerView;
337+
this.flutterApi = flutterApi;
319338
}
320339

321340
/**
@@ -508,6 +527,14 @@ public void setWebChromeClient(Long instanceId, Long clientInstanceId) {
508527
webView.setWebChromeClient((WebChromeClient) instanceManager.getInstance(clientInstanceId));
509528
}
510529

530+
@Override
531+
public void enableListenForScrollPos(Long instanceId, Long webViewClientInstanceId, Boolean enable) {
532+
final WebViewHostApiImpl.WebViewPlatformView webView = (WebViewHostApiImpl.WebViewPlatformView) instanceManager.getInstance(instanceId);
533+
webView.setOnScrollChangedCallback((l, t, oldl, oldt) -> flutterApi.onScrollPosChange(webViewClientInstanceId,
534+
instanceId,
535+
(long) l, (long) t, reply -> {}));
536+
}
537+
511538
@Override
512539
public void setBackgroundColor(Long instanceId, Long color) {
513540
final WebView webView = (WebView) instanceManager.getInstance(instanceId);

packages/webview_flutter/webview_flutter_android/example/lib/main.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ class _WebViewExampleState extends State<_WebViewExample> {
117117
initialUrl: 'https://flutter.dev',
118118
onWebViewCreated: (WebViewController controller) {
119119
_controller.complete(controller);
120+
controller.setOnScrollListener((int x, int y) {
121+
print('New scroll position: x = $x, y = $y');
122+
});
120123
},
121124
onProgress: (int progress) {
122125
print('WebView is loading (progress : $progress%)');

packages/webview_flutter/webview_flutter_android/example/lib/web_view.dart

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ typedef PageLoadingCallback = void Function(int progress);
4040
/// Signature for when a [WebView] has failed to load a resource.
4141
typedef WebResourceErrorCallback = void Function(WebResourceError error);
4242

43+
/// Signature for when a [WebView] scroll position changed.
44+
typedef OnScrollPosChangeCallback = void Function(int x, int y);
45+
4346
/// A web view widget for showing html content.
4447
///
4548
/// The [WebView] widget wraps around the [AndroidWebView] or
@@ -195,7 +198,7 @@ class WebView extends StatefulWidget {
195198
///
196199
/// This callback is only called for the main page.
197200
final WebResourceErrorCallback? onWebResourceError;
198-
201+
199202
/// Controls whether WebView debugging is enabled.
200203
///
201204
/// Setting this to true enables [WebView debugging on Android](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/).
@@ -286,6 +289,7 @@ class _WebViewState extends State<WebView> {
286289
webViewPlatformController!,
287290
_javascriptChannelRegistry,
288291
);
292+
_platformCallbacksHandler._webViewController = controller;
289293
_controller.complete(controller);
290294

291295
if (widget.onWebViewCreated != null) {
@@ -310,9 +314,14 @@ class _WebViewState extends State<WebView> {
310314

311315
class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler {
312316
_PlatformCallbacksHandler(this._webView);
317+
WebViewController? _webViewController;
313318

314319
final WebView _webView;
315320

321+
set webViewController(WebViewController value) {
322+
_webViewController = value;
323+
}
324+
316325
@override
317326
FutureOr<bool> onNavigationRequest({
318327
required String url,
@@ -347,6 +356,11 @@ class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler {
347356
}
348357
}
349358

359+
@override
360+
void onScrollPosChange(int x, int y) {
361+
_webViewController?.onScrollPosChangeCallback?.call(x, y);
362+
}
363+
350364
@override
351365
void onWebResourceError(WebResourceError error) {
352366
if (_webView.onWebResourceError != null) {
@@ -374,6 +388,8 @@ class WebViewController {
374388

375389
final WebViewPlatformController _webViewPlatformController;
376390

391+
OnScrollPosChangeCallback? onScrollPosChangeCallback;
392+
377393
late WebSettings _settings;
378394

379395
WebView _widget;
@@ -600,6 +616,12 @@ class WebViewController {
600616
return _webViewPlatformController.getScrollY();
601617
}
602618

619+
/// Set the scroll listener callback
620+
Future<void> setOnScrollListener(OnScrollPosChangeCallback? callback) {
621+
onScrollPosChangeCallback = callback;
622+
return _webViewPlatformController.enableScrollListener(callback != null);
623+
}
624+
603625
// This method assumes that no fields in `currentValue` are null.
604626
WebSettings _clearUnchangedWebSettings(
605627
WebSettings currentValue, WebSettings newValue) {

packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ class WebView {
365365
return api.setBackgroundColorFromInstance(this, color.value);
366366
}
367367

368+
/// Enable scroll listener for this WebView.
369+
Future<void> enableListenForScrollPos(bool enable) {
370+
return api.enableListenForScrollPosFromInstance(
371+
this, _currentWebViewClient!, enable);
372+
}
373+
368374
/// Releases all resources used by the [WebView].
369375
///
370376
/// Any methods called after [release] will throw an exception.
@@ -745,6 +751,9 @@ abstract class WebViewClient {
745751
/// causes the current [WebView] to abort loading the URL, while returning
746752
/// false causes the [WebView] to continue loading the URL as usual.
747753
void urlLoading(WebView webView, String url) {}
754+
755+
/// Notify a new scroll position for the current [WebView]
756+
void onScrollPosChange(WebView webView, int x, int y) {}
748757
}
749758

750759
/// The interface to be used when content can not be handled by the rendering engine for [WebView], and should be downloaded instead.

0 commit comments

Comments
 (0)