当前位置: 首页 > article >正文

Flutter 使用 flutter_inappwebview 加载 App 本地 HTML 文件

在 Flutter 开发中,加载本地 HTML 文件是一个常见的需求,尤其是在需要展示离线内容或自定义页面时。flutter_inappwebview 是一个功能强大的插件,支持加载本地文件和网络资源。本文将详细介绍如何使用 flutter_inappwebview 加载 App 本地 HTML 文件,包括传统加载资源文件的方法和从 App 目录加载文件的方法。

一、传统加载资源文件

  1. HTML 文件放置
    首先,将 .html 文件拖入工程中。通常,我会将文件放在工程的根目录下,与 pubspec.yaml 同级。
    然后,打开 pubspec.yaml 文件,在 assets: 下添加该文件,例如:
flutter:
  assets:
    - membership_agreement.html
  1. 加载本地 HTML 文件
    接下来,使用 rootBundle 读取文件内容,并通过 InAppWebView 加载 HTML 数据。
    dart复制
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class LocalHtmlPage extends StatefulWidget {
  final String html;

  LocalHtmlPage({required this.html});

  
  _LocalHtmlPageState createState() => _LocalHtmlPageState();
}

class _LocalHtmlPageState extends State<LocalHtmlPage> {
  late InAppWebViewController _webViewController;

  Future<String> _getFile() async {
    return await rootBundle.loadString(widget.html);
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("加载本地 HTML 文件")),
      body: FutureBuilder<String>(
        future: _getFile(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final String htmlUrl = Uri.dataFromString(
              snapshot.data!,
              mimeType: 'text/html',
              encoding: Encoding.getByName('utf-8'),
              base64: true,
            ).toString();
            return InAppWebView(
              initialUrlRequest: URLRequest(url: Uri.parse(htmlUrl)),
              onWebViewCreated: (controller) {
                _webViewController = controller;
              },
              onLoadStart: (controller, url) {
                print('开始加载: $url');
              },
              onLoadStop: (controller, url) {
                print('加载完毕: $url');
              },
              onConsoleMessage: (controller, consoleMessage) {
                print('Console message: ${consoleMessage.message}');
              },
            );
          }
          return Center(child: Text('读取失败'));
        },
      ),
    );
  }
}

二、加载 App 目录文件

  1. 需求背景
    在某些场景下,HTML 文件可能需要先下载到 App 的本地目录,然后再从目录中加载。例如,从网络下载 HTML 文件并保存到本地缓存目录。
  2. 核心代码
    以下是使用 flutter_inappwebview 加载 App 目录中的 HTML 文件的完整代码示例:
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:path_provider/path_provider.dart';

class LocalHtmlPage extends StatefulWidget {
  final String htmlFileName;

  LocalHtmlPage({required this.htmlFileName});

  
  _LocalHtmlPageState createState() => _LocalHtmlPageState();
}

class _LocalHtmlPageState extends State<LocalHtmlPage> {
  late InAppWebViewController _webViewController;

  Future<File?> getLocalHtmlFile() async {
    final directory = await getApplicationDocumentsDirectory();
    final filePath = "${directory.path}/${widget.htmlFileName}";
    final file = File(filePath);
    if (await file.exists()) {
      return file;
    }
    return null;
  }

  Future<void> load() async {
    try {
      final file = await getLocalHtmlFile();
      if (file != null) {
        print('加载本地 HTML 文件: file://${file.path}');
        _webViewController.loadUrl(
          urlRequest: URLRequest(url: Uri.file(file.path)),
        );
      } else {
        print('文件不存在');
      }
    } catch (e, stackTrace) {
      print('加载本地 HTML 文件异常: $e');
      print(stackTrace);
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("加载本地 HTML 文件")),
      body: InAppWebView(
        onWebViewCreated: (controller) {
          _webViewController = controller;
          load();
        },
        onLoadStart: (controller, url) {
          print('开始加载: $url');
        },
        onLoadStop: (controller, url) {
          print('加载完毕: $url');
        },
        onProgressChanged: (controller, progress) {
          print('WebView 加载中 (进度: $progress%)');
        },
        onConsoleMessage: (controller, consoleMessage) {
          print('Console message: ${consoleMessage.message}');
        },
        gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
          Factory(() => EagerGestureRecognizer()),
        }.toSet(),
      ),
    );
  }
}

三、注意事项
文件路径问题:
确保文件路径正确,并且文件确实存在于指定路径下。
如果文件路径是动态生成的,确保路径格式正确。
文件内容问题:
确保 HTML 文件内容是有效的,且没有语法错误。
可以在浏览器中直接打开该 HTML 文件,确认其是否正常显示。
iOS 网络权限:
如果加载的文件路径是 file://,确保 iOS 的网络权限配置正确。在 Info.plist 中添加以下配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

日志输出:
如果需要关闭日志输出,可以在 Dart 代码中过滤日志消息,或在 iOS 和 Android 项目中配置日志级别。
通过以上方法,你可以灵活地使用 flutter_inappwebview 加载本地 HTML 文件,无论是通过资源文件还是从 App 目录加载。希望本文能帮助你更好地实现这一功能。


http://www.kler.cn/a/515564.html

相关文章:

  • 回归人文主义,探寻情感本质:从文艺复兴到AI时代,我的情感探索之旅
  • IP协议格式
  • AIGC视频生成模型:ByteDance的PixelDance模型
  • Java如何向http/https接口发出请求
  • Mixly米思齐1.0 2.0 3.0 软件windows版本MAC苹果电脑系统安装使用常见问题与解决
  • Kubernetes 集群中安装和配置 Kubernetes Dashboard
  • QT:控件属性及常用控件(3)-----输入类控件(正则表达式)
  • TangoFlux 本地部署实用教程:开启无限音频创意脑洞
  • Threejs的学习-几何点线面
  • 神经网络|(一)加权平均法,感知机和神经元
  • Linux 切换到 Root 用户的方式及差异详解
  • Vue平台开发三——项目管理页面
  • 用于牙科的多任务视频增强
  • C++priority_queue模拟实现
  • linux 下调试 pac1934 电源监控器
  • AutoPrompt框架和实操:如何用AutoPrompt完成电影评论和聊天审核任务?
  • python内置的调试工具-pdb
  • 解决SpringBoot项目启动错误:找不到或无法加载主类
  • 一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk
  • 【玩转全栈】----基于ModelForm完成用户管理页面
  • 作品显示ip属地与定位哪个是真实的
  • 解决因JDK升级导致的`java.nio.file.NoSuchFileException`问题
  • 【K8S问题系列 |19 】如何解决 Pod 无法挂载 PVC问题
  • Python并发编程 07 事件驱动模型、进程切换、进程阻塞、文件描述符、缓存I/O、selectors模块
  • Vue3+Element Plus 实现 el-table 表格组件滚动是否触底监听判断
  • 父级perspective与子元素transform:perspective的区别