I want to detect scrolling in WebView_Flutter and hide the padding

2.2k Views Asked by At

I am using Webview_Flutter. The header of the site overlaps the position of the statusbar and I would like to add padding to avoid this.

This is the process of inserting padding to avoid the statusbar if the webview is opened or if there is a scroll position at the top.

    body: Padding(
          padding: (controller?.getScrollY() == null || controller?.getScrollY() == 0)
              ? EdgeInsets.only(top: height)
              : EdgeInsets.only(top: 0),
          child: Expanded(
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 0.0),
                      child: WebView(
                        javascriptMode: JavascriptMode.unrestricted,
                        initialUrl: Uri.parse(widget.link).toString(),
                        onWebResourceError: (error) {
                          // print(error.domain);
                        },
                        onWebViewCreated: (controller) {
                          this.controller = controller;
                        },
                        onProgress: (progress) {
                          setState(() {
                            this.progress = progress / 100;
                            progressPercent = progress;
                          });
                        },
                      ),
              
2

There are 2 best solutions below

0
Lorenzo Pichilli On BEST ANSWER

To detect WebView scroll event, you can use the flutter_inappwebview plugin (I'm the author) and implement the InAppWebView.onScrollChanged event.

However, probably you don't need to add top padding for your WebView. You can set the AppBar.toolbarHeight to 0, so the app bar will have the right height to cover the status bar.

Here is a full code example with both cases using the current latest version 6 available of the plugin (6.0.0-beta.16):

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (!kIsWeb &&
      kDebugMode &&
      defaultTargetPlatform == TargetPlatform.android) {
    await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
  }
  runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController? webViewController;

  int scrollY = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          toolbarHeight: 0,
        ),
        body: Padding(
          padding: EdgeInsets.only(top: scrollY <= 0 ? 25 : 0),
          child: Column(
            children: [
              Expanded(
                child: InAppWebView(
                  key: webViewKey,
                  initialUrlRequest:
                      URLRequest(url: WebUri("https://github.com/flutter")),
                  onWebViewCreated: (controller) {
                    webViewController = controller;
                  },
                  onScrollChanged: (controller, x, y) {
                    setState(() {
                      scrollY = y;
                    });
                  },
                ),
              )
            ],
          ),
        ));
  }
}

Simulator Screen Recording - iPhone 14 Pro Max - 2022-11-25 at 01 21 15

0
Imen A. On

I tried to find the listener of the webView scroll, I couldn't find it , you're right. There is a solution ^^, it's simple, we could wrap WebView in ListView then we could use scrollListener(1) or notificationListener(2) and don't forget to use setState to update Padding values

class _HomeScreenState extends State<HomeScreen> {
    WebViewController? _webViewController;
    ScrollController _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return
      Scaffold(
        body:Scaffold(
          backgroundColor: Colors.green,
          appBar: AppBar(
            title: const Text('Flutter WebView example'),
            // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
            actions: <Widget>[

            ],
          ),
//NotificationListener(2)
          body: NotificationListener<ScrollNotification>(
            onNotification: (scrollNotification) {
              if (scrollNotification is ScrollStartNotification) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
              print("ScrollStartNotification / pixel => ${scrollNotification.metrics.pixels}");
            });

          } else if (scrollNotification is ScrollEndNotification) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
              setState(() {
                print("ScrollEndNotification / pixel =>${scrollNotification.metrics.pixels}");
              });
            });
          }

              return true;
            },
            child: ListView(
              physics: ClampingScrollPhysics(),
              controller: _scrollController,
              children: <Widget>[
                ConstrainedBox(
                    constraints: BoxConstraints(maxHeight: 10000),
                    child: WebView(
                      initialUrl: 'https://flutter.dev',
                      javascriptMode: JavascriptMode.unrestricted,
                      onWebViewCreated: (WebViewController webViewController) {},
                      onProgress: (int progress) {
                        print('WebView is loading (progress : $progress%)');
                      },
                      javascriptChannels: <JavascriptChannel>{
                      },
                      onPageStarted: (String url) {},
                      onPageFinished: (String url) {},
                      gestureNavigationEnabled: true,
                      backgroundColor: const Color(0x00000000),
                    ),
                ),
              ],
            ),
          )));


  }

    @override
  void initState() {
     super.initState();
//scrollListener(1)
     _scrollController.addListener(() {
       print("scrollListener / pixel =>${_scrollController.position.pixels}");
     });
  }
}