Reputation: 499
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
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
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
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