You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebView_Flutter滚动检测与状态栏遮挡适配方案问询

解决WebView_Flutter与状态栏重叠的动态内边距方案

针对WebView头部和状态栏重叠的问题,可通过动态调整顶部内边距实现:页面初始加载或滚动到顶部时,添加与状态栏等高的内边距避开遮挡;页面滚动后移除该内边距。以下是完整实现代码及关键说明:

完整实现代码

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewPage extends StatefulWidget {
  final String link;
  const WebViewPage({super.key, required this.link});

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  WebViewController? controller;
  double progress = 0;
  int progressPercent = 0;
  // 状态栏高度
  late double statusBarHeight;
  // 当前滚动位置
  double scrollY = 0;

  @override
  void initState() {
    super.initState();
    // 获取当前设备状态栏高度
    statusBarHeight = MediaQuery.of(context).padding.top;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          // 可选:加载进度条
          if (progress < 1)
            LinearProgressIndicator(value: progress, backgroundColor: Colors.grey[200]),
          Expanded(
            child: Padding(
              // 根据滚动位置动态设置顶部内边距
              padding: EdgeInsets.only(top: scrollY == 0 ? statusBarHeight : 0),
              child: WebView(
                javascriptMode: JavascriptMode.unrestricted,
                initialUrl: Uri.parse(widget.link).toString(),
                onWebResourceError: (error) {
                  // 处理网页加载错误
                },
                onWebViewCreated: (controller) {
                  this.controller = controller;
                  // 注册JS通信通道,接收滚动位置
                  controller.addJavascriptChannel(
                    'ScrollChannel',
                    onMessageReceived: (message) {
                      setState(() {
                        scrollY = double.parse(message.message);
                      });
                    },
                  );
                },
                onPageFinished: (url) {
                  // 页面加载完成后注入JS,监听滚动事件
                  controller?.runJavascript('''
                    window.addEventListener('scroll', function() {
                      ScrollChannel.postMessage(window.scrollY.toString());
                    });
                    // 初始发送一次滚动位置(确保页面加载时的状态正确)
                    ScrollChannel.postMessage(window.scrollY.toString());
                  ''');
                },
                onProgress: (progress) {
                  setState(() {
                    this.progress = progress / 100;
                    progressPercent = progress;
                  });
                },
              ),
            ),
          ),
        ],
      ),
    );
  }
}

关键实现说明

  • 状态栏高度适配:通过MediaQuery.of(context).padding.top获取当前设备的状态栏高度,自动适配不同机型的状态栏差异
  • JS与Flutter通信:借助JavascriptChannel建立网页和Flutter的双向通信,网页滚动时主动将滚动位置发送给Flutter
  • 动态内边距切换:根据scrollY的值判断页面状态,当滚动位置为0(顶部)时添加状态栏高度的内边距,滚动后移除内边距
  • 滚动事件监听时机:在onPageFinished回调中注入JS监听代码,确保页面完全加载后才开始监听滚动状态,避免无效调用

内容的提问来源于stack exchange,提问作者Tdayo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:55:17