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

Flutter WebView如何实现自动缩放或设置宽度?

实现WebView自动缩放适配容器的方案

一、基于webview_flutter的原生配置实现

webview_flutter本身支持通过配置和JavaScript注入实现页面自动缩放,适配容器尺寸:

1. 配置WebViewController实现自适应缩放

通过WebViewController配置平台特定参数,结合页面加载完成后的JS计算,自动适配容器大小:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late WebViewController _webViewController;
  final double _chartContainerHeight = 150;

  @override
  void initState() {
    super.initState();
    _webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse('https://thingspeak.com/channels/1864145/charts/1?bgcolor=%23ffffff&color=%23d62020&dynamic=true&results=60&title=Carbon+Dioxide+Concentrations&type=line'))
      // 配置平台缩放参数
      ..setWebViewConfiguration(WebViewConfiguration(
        android: AndroidWebViewConfiguration(
          settings: AndroidSettings(
            builtInZoomControls: true,
            displayZoomControls: false,
            loadWithOverviewMode: true,
            useWideViewPort: true,
          ),
        ),
        ios: IOSWebViewConfiguration(
          allowsZooming: true,
        ),
      ))
      // 页面加载完成后自动计算缩放比例
      ..setNavigationDelegate(NavigationDelegate(
        onPageFinished: (url) {
          _webViewController.runJavaScript('''
            const contentHeight = document.body.scrollHeight;
            const scale = $_chartContainerHeight / contentHeight;
            document.body.style.transform = `scale(\${scale})`;
            document.body.style.transformOrigin = 'top center';
            document.body.style.margin = '0';
          ''');
        },
      ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFFCFCFC),
      appBar: AppBar(
        centerTitle: true,
        title: const Text(
          'test',
          style: TextStyle(
            fontSize: 28.0,
            fontWeight: FontWeight.bold,
            letterSpacing: 2.5,
          ),
        ),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Container(
              height: _chartContainerHeight,
              width: MediaQuery.of(context).size.width,
              child: WebViewWidget(controller: _webViewController),
              color: Colors.blue,
            ),
          ],
        ),
      ),
    );
  }
}

2. 注入Viewport元标签优化适配

如果目标网页的viewport配置不合理,可在页面加载完成后注入自定义viewport:

// 在onPageFinished的JS代码中添加
var meta = document.createElement('meta');
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', 'width=device-width, initial-scale=1.0, user-scalable=yes');
document.getElementsByTagName('head')[0].appendChild(meta);

二、功能更丰富的替代插件推荐

如果webview_flutter的配置无法满足需求,可尝试以下插件:

  • flutter_inappwebview:提供比webview_flutter更全面的原生WebView控制能力,支持灵活的缩放策略、自定义JS注入时机,适配多平台的细节优化。示例用法:

    InAppWebView(
      initialUrlRequest: URLRequest(url: Uri.parse('你的图表URL')),
      initialSettings: InAppWebViewSettings(
        javaScriptEnabled: true,
        useWideViewPort: true,
        loadWithOverviewMode: true,
        builtInZoomControls: true,
        displayZoomControls: false,
      ),
      onLoadStop: (controller, url) async {
        await controller.evaluateJavascript(source: '''
          const contentHeight = document.body.scrollHeight;
          const scale = 150 / contentHeight;
          document.body.style.transform = `scale(\${scale})`;
          document.body.style.transformOrigin = 'top center';
        ''');
      },
    )
    
  • webviewx:封装了webview_flutter和flutter_inappwebview,提供统一API,简化缩放、JS交互等操作,适合快速开发多图表布局场景。

三、多图表布局建议

单页展示多个图表时,建议使用ListView或GridView布局,给每个WebView设置固定高度容器,避免布局溢出:

body: ListView(
  padding: const EdgeInsets.all(16),
  children: [
    Container(
      height: 150,
      margin: const EdgeInsets.only(bottom: 16),
      child: WebViewWidget(controller: _chartController1),
    ),
    Container(
      height: 150,
      margin: const EdgeInsets.only(bottom: 16),
      child: WebViewWidget(controller: _chartController2),
    ),
    // 更多图表容器...
  ],
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:05:30