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的背景色为透明来实现。

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

在上面的示例中,通过WebViewController

setBackgroundColor

方法将WebView的背景色设置为

Colors.transparent

,表示完全透明。

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

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

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

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

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

'MyApp/1.0'

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

setUserAgent

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

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

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

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

在上面的示例中,通过WebViewController

loadRequest

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

headers

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

'X-Custom-Header'

'Authorization'

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

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

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

'User-Agent'

'Referer'

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

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

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

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

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

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

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

enableDebugging

方法,将参数设置为

true

,启用WebView的调试模式。

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

"chrome://inspect"

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

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

enableDebugging

方法的参数设置为

false

来禁用调试模式。

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

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

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

setMediaPlaybackRequiresUserGesture

方法的参数设置为

false

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

设置

setMediaPlaybackRequiresUserGesture

false

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

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

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

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

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

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

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

WebKitWebViewControllerCreationParams

allowsInlineMediaPlayback

属性为

true

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

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

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

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

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

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

WebKitWebViewController

。如果是,则通过将

WebKitWebViewController

setAllowsBackForwardNavigationGestures

方法的参数设置为

false

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

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

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

goBack

goForward

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

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

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

console.log

console.warn

console.error

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

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

import'package:webview_flutter/webview_flutter.dart';// ...// 创建WebView控制器finalWebViewController controller =WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted)..setNavigationDelegate(NavigationDelegate(
      onPageStarted:(String url){// 页面开始加载时添加JavaScript日志监听
        controller.runJavaScript('''
          console.log = function(message) {
            window.flutter_inappwebview.callHandler('consoleLog', message);
          };
          console.warn = function(message) {
            window.flutter_inappwebview.callHandler('consoleWarn', message);
          };
          console.error = function(message) {
            window.flutter_inappwebview.callHandler('consoleError', message);
          };
        ''');},),)..addJavaScriptChannel('flutter_inappwebview',
    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'));// ...

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

setNavigationDelegate

设置了一个NavigationDelegate,并在

onPageStarted

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

我们使用

runJavaScript

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

console.log

console.warn

console.error

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

window.flutter_inappwebview.callHandler

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

接着,我们通过

addJavaScriptChannel

添加了一个名为

flutter_inappwebview

JavaScript通道,并在

onMessageReceived

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

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

consoleLog

consoleWarn

还是

consoleError

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

consoleLog

消息,我们使用

print

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

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

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

onPageFinished

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

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

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

onHttpAuthRequest

回调来处理认证请求。

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

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

这里,我们通过

setNavigationDelegate

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

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

onHttpAuthRequest

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

onHttpAuthRequest

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

'example.com'

的认证请求。

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

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

HttpAuthResponse

对象来提供认证凭据。在

HttpAuthResponse

中,我们设置了用户名(

username

)和密码(

password

),并将

action

属性设置为

HttpAuthResponseAction.proceed

,表示继续进行认证。

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

HttpAuthResponse

对象,并将

action

属性设置为

HttpAuthResponseAction.cancel

,表示取消认证请求。

需要注意的是,

onHttpAuthRequest

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

async

await

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

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

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

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

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

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

Android平台上,需要在

AndroidManifest.xml

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

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

iOS平台上,需要在

Info.plist

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

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

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

onShowFileChooser

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

import'package:webview_flutter/webview_flutter.dart';// ...finalWebViewController controller =WebViewController()..setWebChromeClient(WebChromeClient(
      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{// 实现文件选择器的逻辑// ...}

onShowFileChooser

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

acceptedTypes

)和是否允许多选(

allowMultiple

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

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

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

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

1. 实现下载监听器

可以通过实现WebViewClient

onDownloadStart

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

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

onDownloadStart

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

url

)、文件名(

contentDisposition

)、文件类型(

mimetype

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

2. 请求下载权限(Android)

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

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

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

permission_handler

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

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

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

http

dio

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

http

库下载文件的示例:

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){// 实现显示下载完成通知的逻辑// ...}

_startDownload

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

然后,使用

path_provider

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

Content-Disposition

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

接着,使用

http

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

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

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

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

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

标签: Flutter Dart Webview

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

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

还没有评论