0


Flutter笔记:关于WebView插件的用法(下)

Flutter笔记关于WebView插件的用法(下)

-
文章信息 -
Author: 李俊才 (jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSite:http://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/139613391
HuaWei:https://bbs.huaweicloud.com/blogs/428875


【介绍】:WebView是一个可以在移动应用中显示网页的组件。它基于原生的WebView控件(如iOS中的WKWebView和Android中的WebView),提供了加载URL、显示HTML内容、与JavaScript交互等功能。通过在Flutter应用中使用WebView,我们可以方便地集成Web内容,并与之进行交互。本文介绍Flutter中WebView插件的用法。


上一节:《 关于WebView插件的用法(上) 》

目 录



WebView提供了一些自定义选项,可以根据需求对WebView的外观和行为进行定制。下面我们来详细介绍几种常见的自定义WebView的方法。

默认情况下,WebView的背景色是不透明的白色。如果需要实现WebView的透明效果,可以通过设置WebView的背景色为透明来实现。

  1. // 设置WebView背景色为透明
  2. controller.setBackgroundColor(Colors.transparent);

在上面的示例中,通过WebViewController

  1. setBackgroundColor

方法将WebView的背景色设置为

  1. Colors.transparent

,表示完全透明。

设置透明背景后,WebView的内容将会显示在其下方的Flutter小部件之上。这样可以实现WebView与其他Flutter小部件的叠加和混合效果。

需要注意的是,设置透明背景只会影响WebView的背景色,而不会影响网页内容的背景色。如果网页本身设置了不透明的背景色,那么即使将WebView的背景色设置为透明,网页内容的背景色仍然会保持不透明。

用户代理(User Agent)是一个字符串,用于标识浏览器或客户端的身份和版本信息。WebView默认使用系统提供的用户代理字符串,但有时我们可能需要自定义用户代理以满足特定的需求。

  1. // 自定义用户代理字符串constString userAgent ='MyApp/1.0';await controller.setUserAgent(userAgent);

在上面的示例中,我们定义了一个自定义的用户代理字符串

  1. 'MyApp/1.0'

,表示我们的应用名称和版本号。然后通过WebViewController

  1. setUserAgent

方法将自定义的用户代理字符串设置给WebView

设置自定义用户代理后,WebView在发送HTTP请求时将使用自定义的用户代理字符串,而不是默认的系统用户代理。这可以用于模拟特定的浏览器或客户端,或者向服务器传递额外的信息。

除了自定义用户代理外,还可以在WebView加载页面时设置自定义的HTTP请求头。这可以用于传递额外的信息给服务器,或者满足某些特殊的请求要求。

  1. // 自定义HTTP请求头await controller.loadRequest(Uri.parse('https://example.com'),
  2. headers:{'X-Custom-Header':'Value','Authorization':'Bearer token',},);

在上面的示例中,通过WebViewController

  1. loadRequest

方法加载一个网址,并通过

  1. headers

参数设置自定义的HTTP请求头。这里我们设置了两个自定义请求头:

  1. 'X-Custom-Header'

  1. 'Authorization'

,分别传递了一个自定义的值和身份验证的令牌。

设置自定义HTTP请求头后,WebView在发送HTTP请求时将包含这些自定义的请求头。服务器可以根据这些请求头的值来执行相应的操作,如身份验证、数据过滤等。

需要注意的是,并非所有的请求头都可以被自定义。有些请求头是由浏览器或WebView自动添加的,如

  1. 'User-Agent'

  1. 'Referer'

等。尝试自定义这些请求头可能会被浏览器或WebView忽略或覆盖。

通过合理地使用自定义WebView的选项,如透明背景、自定义用户代理和自定义HTTP请求头,可以根据实际需求对WebView的外观和行为进行定制,提供更加灵活和个性化的用户体验。同时,在自定义时也需要注意与目标网站的兼容性和请求头的限制,以确保WebView能够正常工作。

WebView在不同的平台上提供了一些特定的功能和配置选项。下面我们来详细介绍在Android平台上的一些特性。

Android平台上,WebView提供了一些额外的功能和配置选项,可以根据需求进行定制和控制。

在进行Web开发和调试时,启用WebView的调试模式可以方便地进行调试和问题排查。在Android平台上,可以通过以下方式启用WebView的调试模式:

  1. import'package:webview_flutter_android/webview_flutter_android.dart';// 启用WebView调试模式if(controller.platform isAndroidWebViewController){AndroidWebViewController.enableDebugging(true);}

在上面的示例中,我们首先判断当前的WebView平台是否为AndroidWebViewController。如果是,则通过调用AndroidWebViewController

  1. enableDebugging

方法,将参数设置为

  1. true

,启用WebView的调试模式。

启用调试模式后,可以通过Chrome开发者工具进行Web开发和调试。在Chrome浏览器中打开

  1. "chrome://inspect"

,可以看到当前连接的Android设备和正在运行的WebView实例。点击对应的WebView实例,即可打开Chrome开发者工具,进行元素审查、控制台调试、网络监控等操作。

需要注意的是,启用调试模式会对性能产生一定的影响,因此在生产环境中应该禁用调试模式。可以通过将

  1. enableDebugging

方法的参数设置为

  1. false

来禁用调试模式。

Android平台上,WebView默认要求用户手势(如点击)才能触发媒体(如视频、音频)的播放。这是为了防止自动播放媒体对用户体验的影响。但是,在某些情况下,我们可能希望允许WebView自动播放媒体,无需用户手势。可以通过以下方式控制WebView中媒体播放器的行为:

  1. import'package:webview_flutter_android/webview_flutter_android.dart';// 设置媒体播放器不需要用户手势if(controller.platform isAndroidWebViewController){(controller.platform asAndroidWebViewController).setMediaPlaybackRequiresUserGesture(false);}

在上面的示例中,我们首先判断当前的WebView平台是否为AndroidWebViewController。如果是,则通过将AndroidWebViewController

  1. setMediaPlaybackRequiresUserGesture

方法的参数设置为

  1. false

,来允许WebView自动播放媒体,无需用户手势。

设置

  1. setMediaPlaybackRequiresUserGesture

  1. false

后,WebView中的媒体播放器将可以自动开始播放,无需用户的点击或其他交互操作。这在某些场景下可能很有用,如播放背景音乐、自动播放视频等。

需要注意的是,自动播放媒体可能会对用户体验产生负面影响,尤其是在移动设备上,因为它可能会消耗额外的带宽和电量。因此,在决定是否允许自动播放媒体时,需要根据具体的应用场景和用户需求进行权衡。

通过合理地使用Android平台提供的WebView特性,如调试模式和媒体播放控制,可以方便地进行Web开发和调试,以及根据需求定制WebView的行为。这样可以提供更加灵活和优化的用户体验,同时也要注意不同设置可能带来的影响和权衡。

WebViewiOS平台上提供了一些特定的功能和配置选项,可以根据需求进行定制和控制。下面我们来详细介绍在iOS平台上的一些特性。

iOS平台上,WebView默认不支持内联(inline)的媒体播放,即在网页中嵌入的视频或音频元素无法直接在WebView中播放,而是会跳转到系统的媒体播放器进行播放。如果希望在WebView中实现内联的媒体播放,可以通过以下方式进行配置:

  1. import'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';// 创建WebView控制器时启用内联媒体播放finalWebViewController controller =WebViewController(
  2. initialUrl:'https://example.com',
  3. creationParams:constWebKitWebViewControllerCreationParams(
  4. allowsInlineMediaPlayback:true,),);

在上面的示例中,我们在创建WebViewController时,通过设置

  1. WebKitWebViewControllerCreationParams

  1. allowsInlineMediaPlayback

属性为

  1. true

,来启用WebView的内联媒体播放功能。

启用内联媒体播放后,WebView中嵌入的视频或音频元素将可以直接在WebView内部播放,无需跳转到系统的媒体播放器。这样可以提供更加流畅和一致的用户体验。

需要注意的是,启用内联媒体播放可能会对性能和资源消耗产生一定的影响,因为它需要在WebView中加载和渲染媒体内容。因此,在决定是否启用内联媒体播放时,需要根据具体的应用场景和用户需求进行权衡。

iOS平台上,WebView默认支持通过手势进行页面的前进和后退导航。用户可以通过在WebView中向左或向右滑动来触发页面的前进或后退操作。如果希望禁用WebView的手势导航功能,可以通过以下方式进行配置:

  1. import'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';// 禁用WebView的手势导航if(controller.platform isWebKitWebViewController){(controller.platform asWebKitWebViewController).setAllowsBackForwardNavigationGestures(false);}

在上面的示例中,我们首先判断当前的WebView平台是否为

  1. WebKitWebViewController

。如果是,则通过将

  1. WebKitWebViewController

  1. setAllowsBackForwardNavigationGestures

方法的参数设置为

  1. false

,来禁用WebView的手势导航功能。

禁用手势导航后,用户将无法通过在WebView中滑动来触发页面的前进或后退操作。这在某些场景下可能很有用,例如当你希望完全控制页面导航行为,或者想要避免用户意外触发导航操作时。

需要注意的是,禁用手势导航并不会影响其他的导航方式,如通过代码调用

  1. goBack

  1. goForward

方法,或者点击网页中的链接进行导航。它只是禁用了通过手势触发的导航操作。

通过合理地使用 iOS平台提供的WebView特性,如内联媒体播放和手势导航控制,可以根据需求定制WebView的行为,提供更加优化和个性化的用户体验。同时也要注意不同设置可能带来的影响和权衡,以确保WebView的性能和功能符合应用的要求。

WebView提供了一种监听控制台日志输出的机制,可以捕获网页中的

  1. console.log

  1. console.warn

  1. console.error

等日志信息,并在Flutter应用中进行打印和处理。这对于调试和监控WebView中的JavaScript代码非常有帮助。

下面是一个示例,演示如何监听WebView的控制台日志输出,并在Flutter应用中进行打印:

  1. import'package:webview_flutter/webview_flutter.dart';// ...// 创建WebView控制器finalWebViewController controller =WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted)..setNavigationDelegate(NavigationDelegate(
  2. onPageStarted:(String url){// 页面开始加载时添加JavaScript日志监听
  3. controller.runJavaScript('''
  4. console.log = function(message) {
  5. window.flutter_inappwebview.callHandler('consoleLog', message);
  6. };
  7. console.warn = function(message) {
  8. window.flutter_inappwebview.callHandler('consoleWarn', message);
  9. };
  10. console.error = function(message) {
  11. window.flutter_inappwebview.callHandler('consoleError', message);
  12. };
  13. ''');},),)..addJavaScriptChannel('flutter_inappwebview',
  14. onMessageReceived:(JavaScriptMessage message){// 处理JavaScript日志消息switch(message.message){case'consoleLog':print('WebView Console Log: ${message.arguments}');break;case'consoleWarn':print('WebView Console Warn: ${message.arguments}');break;case'consoleError':print('WebView Console Error: ${message.arguments}');break;}},)..loadRequest(Uri.parse('https://example.com'));// ...

在上面的示例中,我们通过

  1. setNavigationDelegate

设置了一个NavigationDelegate,并在

  1. onPageStarted

回调中添加了JavaScript日志监听。

我们使用

  1. runJavaScript

方法向WebView注入了一段JavaScript代码,重写了

  1. console.log

  1. console.warn

  1. console.error

方法。当网页中调用这些方法时,会通过

  1. window.flutter_inappwebview.callHandler

方法将日志消息发送给Flutter应用。

接着,我们通过

  1. addJavaScriptChannel

添加了一个名为

  1. flutter_inappwebview

JavaScript通道,并在

  1. onMessageReceived

回调中处理接收到的JavaScript日志消息。

根据消息的内容,我们可以判断是

  1. consoleLog

  1. consoleWarn

还是

  1. consoleError

,并相应地进行打印和处理。例如,对于

  1. consoleLog

消息,我们使用

  1. print

语句将日志内容打印到控制台。

通过这种方式,我们就可以实时监听WebView中的控制台日志输出,并在Flutter应用中进行打印和处理。这对于调试和监控WebView中的JavaScript代码非常有帮助,可以方便地查看日志信息,定位问题,并进行相应的处理。

需要注意的是,由于JavaScript日志消息是通过JavaScript通道传递的,因此需要确保WebView已经加载完成,并且JavaScript环境已经准备就绪,才能正确地捕获和处理日志消息。可以在

  1. onPageFinished

回调中添加相应的逻辑,以确保日志监听功能的正常工作。

另外,在处理JavaScript日志消息时,还可以根据需要进行过滤、格式化或存储等操作,以满足不同的调试和监控需求。例如,可以将日志消息写入文件、上传到服务器或与其他调试工具集成,以便进行更全面的分析和追踪。

WebView加载页面时,如果遇到需要HTTP认证的请求,可以通过NavigationDelegate

  1. onHttpAuthRequest

回调来处理认证请求。

下面的例子,展示如何处理WebView的HTTP认证请求:

  1. import'package:webview_flutter/webview_flutter.dart';// ...// 创建WebView控制器finalWebViewController controller =WebViewController()..setNavigationDelegate(NavigationDelegate(
  2. onHttpAuthRequest:(HttpAuthRequest request)async{// 处理HTTP认证请求if(request.host =='example.com'){// 提示用户输入凭据finalString username =await_showUsernameDialog();finalString password =await_showPasswordDialog();// 返回认证凭据returnHttpAuthResponse(
  3. username: username,
  4. password: password,
  5. action:HttpAuthResponseAction.proceed,);}else{// 取消认证请求returnHttpAuthResponse(
  6. action:HttpAuthResponseAction.cancel,);}},),)..loadRequest(Uri.parse('https://example.com'));// ...// 显示用户名输入对话框Future<String>_showUsernameDialog()async{// 实现用户名输入对话框的逻辑// ...}// 显示密码输入对话框Future<String>_showPasswordDialog()async{// 实现密码输入对话框的逻辑// ...}

这里,我们通过

  1. setNavigationDelegate

设置了一个NavigationDelegate,并实现了onHttpAuthRequest回调。

WebView遇到需要HTTP认证的请求时,会触发

  1. onHttpAuthRequest

回调,并传递一个HttpAuthRequest对象,其中包含了认证请求的相关信息,如主机(host)、领域(realm)等。

  1. onHttpAuthRequest

回调中,我们可以根据请求的主机或其他条件来决定是否处理认证请求。例如,在示例中,我们只处理主机为

  1. 'example.com'

的认证请求。

如果决定处理认证请求,可以提示用户输入凭据(如用户名和密码)。这里我们使用了两个自定义的函数_showUsernameDialog和_showPasswordDialog来显示用户名和密码的输入对话框,并获取用户输入的值。

获取到用户输入的凭据后,我们可以通过返回一个

  1. HttpAuthResponse

对象来提供认证凭据。在

  1. HttpAuthResponse

中,我们设置了用户名(

  1. username

)和密码(

  1. password

),并将

  1. action

属性设置为

  1. HttpAuthResponseAction.proceed

,表示继续进行认证。

如果决定取消认证请求,可以返回一个

  1. HttpAuthResponse

对象,并将

  1. action

属性设置为

  1. HttpAuthResponseAction.cancel

,表示取消认证请求。

需要注意的是,

  1. onHttpAuthRequest

回调是异步的,因此我们使用

  1. async

  1. await

来处理异步操作,如显示输入对话框和获取用户输入的值。

另外,在处理HTTP认证请求时,还需要考虑安全性和用户体验。应该根据具体的应用场景和安全要求,选择合适的认证方式和交互流程。例如,可以使用安全的认证协议(如HTTPS)、提供明确的用户提示和反馈、限制认证尝试次数等,以保护用户的凭据和隐私。

通过合理地处理WebViewHTTP认证请求,可以实现对受保护资源的访问控制,提高应用的安全性和用户体验。同时,也要注意处理认证请求时的异步性和错误处理,以确保应用的稳定性和可靠性。

WebView中进行文件上传和下载时,需要进行一些特殊的处理和配置,以确保文件的正确传输和用户体验。下面我们分别介绍文件上传和下载的处理方式和注意事项。

WebView加载的网页包含文件上传功能时,可以通过以下步骤来处理文件上传。

1. 配置WebView的文件上传权限

Android平台上,需要在

  1. AndroidManifest.xml

文件中添加文件读取权限,以允许WebView访问设备上的文件:

  1. <uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>

iOS平台上,需要在

  1. Info.plist

文件中添加文件访问权限,以允许WebView访问应用沙盒中的文件:

  1. <key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict>
2. 实现文件选择回调

当网页中触发文件选择操作时,WebView会调用文件选择回调。可以通过实现WebChromeClient

  1. onShowFileChooser

方法来处理文件选择回调:

  1. import'package:webview_flutter/webview_flutter.dart';// ...finalWebViewController controller =WebViewController()..setWebChromeClient(WebChromeClient(
  2. onShowFileChooser:(WebViewController controller,FileChooserParams params)async{// 处理文件选择回调finalList<String> acceptedTypes = params.acceptTypes;final bool allowMultiple = params.mode ==FileChooserMode.openMultiple;// 使用文件选择器让用户选择文件finalList<String> selectedFiles =await_showFilePicker(acceptedTypes, allowMultiple);// 将选择的文件路径返回给WebViewreturn selectedFiles;},),);// ...// 显示文件选择器Future<List<String>>_showFilePicker(List<String> acceptedTypes, bool allowMultiple)async{// 实现文件选择器的逻辑// ...}

  1. onShowFileChooser

回调中,可以获取文件选择的相关参数,如接受的文件类型(

  1. acceptedTypes

)和是否允许多选(

  1. allowMultiple

)。然后,可以使用文件选择器(如文件管理器或自定义的文件选择器)让用户选择文件。

选择文件后,将选择的文件路径作为List<String>返回给WebViewWebView会自动将这些文件上传到服务器。

需要注意的是,文件选择器的实现方式可能因平台而异。在Android平台上,可以使用IntentActivityResultLauncher来启动文件选择器并获取选择的文件路径。在iOS平台上,可以使用UIDocumentPickerViewController来显示文件选择器并获取选择的文件URL。

WebView加载的网页触发文件下载时,可以通过以下步骤来处理文件下载:

1. 实现下载监听器

可以通过实现WebViewClient

  1. onDownloadStart

方法来监听文件下载事件:

  1. import'package:webview_flutter/webview_flutter.dart';// ...finalWebViewController controller =WebViewController()..setWebViewClient(WebViewClient(
  2. onDownloadStart:(String url,String userAgent,String contentDisposition,String mimetype, int contentLength){// 处理文件下载_startDownload(url, contentDisposition, mimetype);},),);// ...// 开始下载文件void_startDownload(String url,String contentDisposition,String mimetype)async{// 实现文件下载的逻辑// ...}

  1. onDownloadStart

回调中,可以获取下载文件的相关信息,如下载地址(

  1. url

)、文件名(

  1. contentDisposition

)、文件类型(

  1. mimetype

)等。然后,可以使用这些信息来开始文件下载。

2. 请求下载权限(Android)

Android平台上,需要请求文件写入权限,以允许WebView将文件保存到设备上。可以在AndroidManifest.xml文件中添加以下权限:

  1. <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

此外,还需要在运行时动态请求文件写入权限。可以使用

  1. permission_handler

插件来简化权限请求的过程:

  1. import'package:permission_handler/permission_handler.dart';// ...// 请求文件写入权限Future<bool>_requestWritePermission()async{finalPermissionStatus status =awaitPermission.storage.request();return status ==PermissionStatus.granted;}
3. 下载文件

获得必要的权限后,可以使用

  1. http

  1. dio

等网络库来下载文件。下面是一个使用

  1. http

库下载文件的示例:

  1. import'package:http/http.dart'as http;import'package:path_provider/path_provider.dart';import'dart:io';// ...// 开始下载文件void_startDownload(String url,String contentDisposition,String mimetype)async{// 请求文件写入权限(Android)if(Platform.isAndroid){final bool hasPermission =await_requestWritePermission();if(!hasPermission){// 没有文件写入权限,取消下载return;}}// 创建下载目录finalDirectory directory =awaitgetApplicationDocumentsDirectory();finalString filePath ='${directory.path}/${_getFileNameFromContentDisposition(contentDisposition)}';// 发起下载请求finalhttp.Response response =await http.get(Uri.parse(url));// 将下载的文件写入本地finalFile file =File(filePath);await file.writeAsBytes(response.bodyBytes);// 通知用户下载完成_showDownloadCompleteNotification(filePath);}// 从Content-Disposition头中提取文件名String_getFileNameFromContentDisposition(String contentDisposition){// 实现从Content-Disposition头中提取文件名的逻辑// ...}// 显示下载完成通知void_showDownloadCompleteNotification(String filePath){// 实现显示下载完成通知的逻辑// ...}

  1. _startDownload

方法中,首先判断是否有文件写入权限(Android平台)。如果没有权限,则取消下载。

然后,使用

  1. path_provider

插件获取应用的文档目录,并根据

  1. Content-Disposition

头中的文件名生成本地文件路径。

接着,使用

  1. http

库发起下载请求,并将下载的文件写入本地文件系统。

最后,可以显示一个下载完成的通知,提示用户文件已成功下载。

需要注意的是,在处理文件下载时,还需要考虑以下几点:

  • 错误处理:下载过程中可能会出现网络错误、文件写入错误等异常情况,需要进行适当的错误处理和用户提示。
  • 下载进度:对于大文件的下载,可以显示下载进度,以提供更好的用户体验。可以通过监听下载进度事件来实现。
  • 下载管理:如果应用支持多个文件同时下载,可以实现一个下载管理器,用于管理和跟踪所有的下载任务。

通过合理地处理WebView的文件下载,可以为用户提供方便的文件下载功能,同时确保下载过程的稳定性和可靠性。

标签: Flutter Dart Webview

本文转载自: https://blog.csdn.net/qq_28550263/article/details/139613391
版权归原作者 jcLee95 所有, 如有侵权,请联系我们删除。

“Flutter笔记:关于WebView插件的用法(下)”的评论:

还没有评论