Flutter应用开发之webview_flutter插件

简介

在移动应用开发中,经常会遇到加载网页的需求,打开网页通常有两种方式,即在应用内使用内置的组件打开和使用系统自带的浏览器打开。不过,在Flutter应用开发中,由于官方并没有提供类似Webview的网页加载组件,所以如果项目中涉及网页加载需要使用第三方插件库,如webview_flutter、flutter_webview_plugin等。

其中,webview_flutter是Flutter官方开发和维护的网页加载插件库,而flutter_webview_plugin则是Flutter开源社区推出的网页加载插件。两个插件功能都差不多,都支持加载本地html文本、Flutter调用js以及js调用Flutter等,但是我建议使用官方推出的插件,因为它会持续的跟进已知的问题。

和其他Flutter插件的使用方式一样,使用webview_flutter之前需要先在pubspec.yaml文件中添加依赖脚本,如下所示。

dependencies:

webview_flutter: ^0.3.22+1

然后,我们使用flutter packages get命令将webview_flutter插件拉取到本地后,就可以使用它进行网页加载开发了。

基本使用

如下所示,是WebView组件的构造函数。

WebView({

Key key,

this.onWebViewCreated, //WebView创建完成之后的回调

this.initialUrl, // 初始化 URL

this.javascriptMode = JavascriptMode.disabled, //JS执行模式,默认是不调用

this.javascriptChannels, // JS可以调用Flutter 的通道

this.navigationDelegate, // 路由委托,可以使用它执行拦截操作

this.gestureRecognizers, // 手势相关

this.onPageStarted, //开始加载页面回调

this.onPageFinished, // 页面加载完成的回调

this.onWebResourceError, //资源加载失败回调

this.debuggingEnabled = false,

this.gestureNavigationEnabled = false,

this.userAgent,

this.initialMediaPlaybackPolicy =

AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,

})

使用时,只需要按照参数传递对应的值即可。不过,在实际使用前,为了方便使用,我们一般会对它进行二次封装,主要是界面和功能的封装。下面是我封装的一个可以加载本地和网络文件的WebViewPage。

class WebViewPage extends StatefulWidget {

String url;

final String title;

final bool isLocalUrl;

WebViewController _webViewController;

WebViewPage({this.url, this.isLocalUrl = false, this.title});

@override

_WebViewPage createState() => _WebViewPage();

}

class _WebViewPage extends State<WebViewPage> {

JavascriptChannel jsBridge(BuildContext context) => JavascriptChannel(

name: 'jsbridge', // 与h5 端的一致 不然收不到消息

onMessageReceived: (JavascriptMessage message) async{

debugPrint(message.message);

});

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: _buildAppbar(),

body: _buildBody()

);

}

_buildAppbar() {

return AppBar(

elevation: 0,

backgroundColor: Color(0xccd0d7),

title: Text(widget.title, style: TextStyle(color: Colors.black),),

centerTitle: true,

leading: IconButton(icon: Icon(Icons.arrow_back, color: Color(0xFF23ADE5),), onPressed: () {

})

);

}

_buildBody() {

return Column(

children: <Widget>[

SizedBox(

height: 1,

width: double.infinity,

child: const DecoratedBox(decoration: BoxDecoration(color: Color(0xFFEEEEEE))),

),

Expanded(

flex: 1,

child: WebView(

initialUrl: widget.isLocalUrl ? Uri.dataFromString(widget.url, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))

.toString(): widget.url,

javascriptMode: JavascriptMode.unrestricted,

javascriptChannels: <JavascriptChannel>[

jsBridge(context)

].toSet(),

onWebViewCreated: (WebViewController controller){

widget._webViewController = controller;

if(widget.isLocalUrl){

_loadHtmlAssets(controller);

}else{

controller.loadUrl(widget.url);

}

controller.canGoBack().then((value) => debugPrint(value.toString()));

controller.canGoForward().then((value) => debugPrint(value.toString()));

controller.currentUrl().then((value) => debugPrint(value));

},

onPageFinished: (String value){

widget._webViewController.evaluateJavascript('document.title')

.then((title) => debugPrint(title));

},

),

)

],

);

}

//加载本地文件

_loadHtmlAssets(WebViewController controller) async {

String htmlPath = await rootBundle.loadString(widget.url);

controller.loadUrl(Uri.dataFromString(htmlPath,mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))

.toString());

}

}

使用时,只需要按照传入对应的属性即可。需要说明的是,加载本地Html文件时,需要在pubspec.yaml文件中申明这个Html文件,如下所示。

flutter:

// ...

assets:

- assets/real_data_help.html

然后,我们使用封装的组件即可加载本地的Html文件。例如:

class MyApp extends StatelessWidget {

String localUrl = 'assets/real_data_help.html';

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Demo',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home:WebViewPage(url:localUrl, isLocalUrl: true, title: '加载本地文件'),

);

}

}

运行代码,效果下图所示。
在这里插入图片描述

以上是 Flutter应用开发之webview_flutter插件 的全部内容, 来源链接: utcz.com/a/31523.html

回到顶部