本文中用到的插件有
跳转外部浏览器插件 url_launcher
在App内部打开网页的插件 webview_flutter
在组件中加载Html片段的插件flutter_html
插件的引入
上面三个插件按需引入
flutter_html: ^3.0.0-alpha.3
webview_flutter: ^3.0.2
url_launcher: ^6.1.0
需要实现的方法
加载在线网页
WebView(
initialUrl: : _url,
//是否开启JS
javascriptMode: JavascriptMode.unrestricted,
///WebView创建
onWebViewCreated: _onWebViewCreated,
///页面开始加载
onPageStarted: _onPageStarted,
///页面加载家属
onPageFinished: _onPageFinished,
///如果出现错误
onWebResourceError: (WebResourceError error) =>
debugPrint('error:${error.description}'),
)),
void _onWebViewCreated(WebViewController controller) async {
webViewController = controller;
_controller.complete(controller);
webViewController!.clearCache();
}
void _onPageStarted(String url) {
EasyLoading.show();
}
void _onPageFinished(String url) async {
EasyLoading.dismiss();
}
加载本地网页
加载本地网页的时候需要在WebViewCreated的时候调用方法来获取本地html文件
_loadHtmlFromAssets() async {
String fileHtmlContents = await rootBundle.loadString(_url);
webViewController?.loadUrl(Uri.dataFromString(fileHtmlContents,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString());
}
加载本地html片段
这里使用的是HTML插件 封装起来非常的简单
class HtmlRichText extends StatelessWidget {
final String richText;
final Map<String, Style>? style;
const HtmlRichText({Key? key, this.richText = "内容为空", this.style})
: super(key: key);
@override
Widget build(BuildContext context) {
return ListView(
children: [
Html(
data: richText,
style: style ?? {},
)
],
);
}
}
使用
onJumpTo 这个是你之前定义路由器的时候跳转方法 这里需要你自己去实现
加载网络地址
onJumpTo(name: RouterName.webViewPage, arguments: <String, dynamic>{
"title": "百度一下,
"url": "https://www.baidu.com",
"isLocalUrl": false,
});
加载 本地地址
onJumpTo(name: RouterName.webViewPage, arguments: <String, dynamic>{
"title": "我自己的文件,
/// 你自己存储的文件路径 这个路径还需要在 pubspec.yaml中注册
"url": "assets/html/html.html",
"isLocalUrl": true,
});
加载代码段
onJumpTo(name: RouterName.webViewPage, arguments: <String, dynamic>{
"title": "一个代码片段,
"url": "",//代码段的时候网址置为空
"isLocalUrl": true,//本地是true
"richText": ''' <br/>3、用户不得利用“一个Demo”账号或本服务制作、上载、复制、发布、传播如下干扰“服务”正常运营,以及侵犯其他用户或第三方合法权益的内容:
<br/>(1) 含有任何性或性暗示的; <br/>(2) 含有辱骂、恐吓、威胁内容的; <br/>(3) 含有骚扰、垃圾广告、恶意信息、诱骗信息的; <br/>(4)
涉及他人隐私、个人信息或资料的; <br/>(5) 侵害他人名誉权、肖像权、知识产权、商业秘密等合法权利的; <br/>(6)
含有其他干扰本服务正常运营和侵犯其他用户或第三方合法权益内容的信息。 <br/> <br/>''' //一段文字用三个引号控制
}
完整代码
class WebViewPage extends StatefulWidget {
final Map<String, dynamic>? arguments;
const WebViewPage({Key? key, this.arguments}) : super(key: key);
@override
State<WebViewPage> createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
WebViewController? webViewController;
final Completer<WebViewController> _controller =
Completer<WebViewController>();
String _title = "";
String _url = "";
String _richText = "";
bool _isLocalUrl = false;
bool _isShowAppBar = true;
@override
void initState() {
super.initState();
_title = StringUtil.isNotEmpty(widget.arguments?["title"])
? widget.arguments!["title"]
: "";
_url = StringUtil.isNotEmpty(widget.arguments?["url"])
? widget.arguments!["url"]
: "";
_richText = StringUtil.isNotEmpty(widget.arguments?["richText"])
? widget.arguments!["richText"]
: "";
_isLocalUrl = widget.arguments?["isLocalUrl"] ?? false;
_isShowAppBar = widget.arguments?["isShowAppBar"] ?? true;
}
@override
void dispose() {
EasyLoading.dismiss();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:
_isShowAppBar ? ComAppBar.buildNormal(center: Text(_title)) : null,
body: WillPopScope(
onWillPop: () async {
goBack();
return false;
},
child: ((StringUtil.isEmpty(_url) && !_isLocalUrl) ||
(_isLocalUrl &&
(StringUtil.isEmpty(_richText) &&
StringUtil.isEmpty(_url))))
? Container(
padding: EdgeInsets.all(ScreenHelper.width(18)),
child: const Center(
child: Text("当前路径为空"),
),
)
: _isLocalUrl && StringUtil.isNotEmpty(_richText)
? HtmlRichText(
richText: _richText,
)
: WebView(
initialUrl: _isLocalUrl ? "" : _url,
//是否开启JS
javascriptMode: JavascriptMode.unrestricted,
///WebView创建
onWebViewCreated: _onWebViewCreated,
///页面开始加载
onPageStarted: _onPageStarted,
///页面加载家属
onPageFinished: _onPageFinished,
///如果出现错误
onWebResourceError: (WebResourceError error) =>
debugPrint('error:${error.description}'),
)),
);
}
goBack() async {
if (webViewController == null) {
NavigatorUtil().pop();
return;
}
bool goBack = await webViewController!.canGoBack();
if (goBack) {
webViewController!.goBack();
} else {
NavigatorUtil().pop();
}
}
void _onWebViewCreated(WebViewController controller) async {
webViewController = controller;
if (_isLocalUrl) {
await _loadHtmlFromAssets();
}
_controller.complete(controller);
webViewController!.clearCache();
}
void _onPageStarted(String url) {
EasyLoading.show();
}
void _onPageFinished(String url) async {
if (_isLocalUrl) {
//加载js文件
// String jsContent = await rootBundle.loadString(jsPath);
// webViewController?.runJavascript(jsContent);
//加载js脚本 _webViewController.runJavascriptReturningResult("setname('hsw')").then((value) => {
// print(value)
}
EasyLoading.dismiss();
}
_loadHtmlFromAssets() async {
String fileHtmlContents = await rootBundle.loadString(_url);
webViewController?.loadUrl(Uri.dataFromString(fileHtmlContents,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString());
}
}