Ahmed Yusuf
Ahmed Yusuf

Reputation: 499

How to detect scroll end on flutter webview?

I'm currently building an application using flutter with webview for mobile. how to detect scroll when it reaches the end of line of a website page in webview?

Upvotes: 9

Views: 4668

Answers (3)

Siddharth Sogani
Siddharth Sogani

Reputation: 349

With webview_flutter (4.2.1) you add javascript channel to webview controller and listen to message received on it. From webview you can send scroll progress messages to this channel. Inside onMessageReceived you can get progress:

Future<void> fetchArticle() async {
    late final PlatformWebViewControllerCreationParams params;
    params = const PlatformWebViewControllerCreationParams();

    final WebViewController controller =
        WebViewController.fromPlatformCreationParams(params);

    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..addJavaScriptChannel(
        'ARTICLE_SCROLL_CHANNEL',
        onMessageReceived: (progress) {
          setState(() {
            position = double.parse(progress.message) / 100;
          });
        },
      )
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageFinished: (String url) {
            _controller.runJavaScript(
              '''
              window.addEventListener('scroll', function() {
                progress = (this.scrollY / ( document.body.scrollHeight - window.innerHeight ) ) * 100;
                window.ARTICLE_SCROLL_CHANNEL.postMessage(progress);
              });
              ''',
            );
          },
        ),
      )
      ..loadRequest(Uri.parse('https://flutter.dev'));

    _controller = controller;
  }

Upvotes: 1

Ahmed Yusuf
Ahmed Yusuf

Reputation: 499

I solved this problem by adding this script on flutter side

WebView(
    initialUrl: "http://url.com/tos",
    javascriptMode: JavascriptMode.unrestricted,
    javascriptChannels: [
    JavascriptChannel(
        name: 'FLUTTER_CHANNEL',
        onMessageReceived: (message) {
            if (message.message.toString() ==
                "end of scroll") {
                setState((){ 
                    enableAgreeButton = true; 
                });
            }
        })
    ].toSet(),
    gestureNavigationEnabled: true,
    debuggingEnabled: true,
)

and this on js side

<script>
window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
    window.FLUTTER_CHANNEL.postMessage('end of scroll');
    }
};
</script>

thanks to nsNeruno and Starscream for the insight

Upvotes: 9

Tomislav Juroš
Tomislav Juroš

Reputation: 370

I had the same problem, so I import syncfusion_flutter_pdfviewer. You can set controller on this viewer and use listener.

It can be done through Javascript with webview, but it is a little bit complicated.

Upvotes: 3

Related Questions