柚子快報邀請碼778899分享:flutter:webview
柚子快報邀請碼778899分享:flutter:webview
前言
最近在研究如何在應(yīng)用程序中嵌入Web視圖,發(fā)現(xiàn)有兩個庫不錯。 一個是官方維護、一個是第三方維護。因為沒說特別的需求,就使用了官方庫,實現(xiàn)一些簡單功能是完全ok的
webview_flutter
不建議使用,因為效果不怎么樣,當然也可能是我太菜不會用,下面這個問題就很難理解為什么會這樣?
基本使用
官方文檔
https://pub-web.flutter-io.cn/packages/webview_flutter
安裝
flutter pub add webview_flutter
加載并顯示web 可以加載html字符串,也可以直接加載url鏈接。官方都提供了對應(yīng)的方法,這里演示加載url
初始化
late WebViewController webViewController;
//初始化
@override
void initState() {
super.initState();
webViewController = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted);
}
顯示 顯示的時候一般需要結(jié)合FutureBuilder,比較這是一個異步的過程
FutureBuilder(
// 異步方法
future: searchNovelFromWeb(),
builder: (context, snapshot) {
// 等待狀態(tài)顯示的widget
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
// 錯誤時顯示的widget
} else if (snapshot.hasError) {
return const Text('Error');
} else {
return snapshot.data ?? const Text('No data');
}
}))
Future
Widget res;
try {
await webViewController
.loadRequest(Uri.parse('https://m.bbxxxxxx.com/s?q=凡人修仙'));
res = WebViewWidget(controller: webViewController);
} catch (error) {
res = Text("加載失?。?{error.toString()}");
print("加載失敗:${error.toString()}");
}
return res;
}
flutter與web之間的交互
flutter通知web,讓web執(zhí)行某些操作
官方提供了兩個方法:runJavaScript、runJavaScriptReturningResult。后者可以向flutter返回執(zhí)行結(jié)果 比如在網(wǎng)頁加載完成后獲取到網(wǎng)頁源代碼
webViewController.setNavigationDelegate(
NavigationDelegate(onPageFinished: (url) async {
print("頁面加載完成:$url");
var html = await webViewController.runJavaScriptReturningResult(
"document.documentElement.innerText;");
debugPrint("結(jié)果是11:$html", wrapWidth: 1024);
}));
web發(fā)生變化后,通知flutter 這塊也實現(xiàn)了,但是不太穩(wěn)定,有時候不能夠正常運行
await webViewController
.loadRequest(Uri.parse('https://m.bbxxxxxxxt.com/s?q=凡人修仙'));
webViewController.setNavigationDelegate(
NavigationDelegate(onPageFinished: (url) async {
print("頁面加載完成:$url");
// 添加監(jiān)聽
await webViewController.addJavaScriptChannel('Report',
onMessageReceived: (JavaScriptMessage message) {
print("收到了消息,是:${message.message}");
});
// 注入腳本
await webViewController.runJavaScript('''
setInterval(() => {
let time = new Date().toLocaleTimeString();
Report.postMessage(time);
},1000)
''');
}));
flutter_inappwebview
功能更多,這里只會簡單介紹一下,具體使用可以查看官方文檔、官方案例。
強烈推薦:功能更多,而且原來使用webview_flutter無法實現(xiàn)的功能,現(xiàn)在輕而易舉的實現(xiàn)了。
官方文檔
官方案例
安裝
flutter pub add flutter_inappwebview
基本使用
這里遇到個問題,版本過高導致構(gòu)建失敗了。我現(xiàn)在用的版本是:5.6.0
// 將html字符串解析為dom的庫
import 'package:html/parser.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
late InAppWebViewController inAppWebViewController;
res = InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse('https://onion.inscode.cc/')),
onLoadStop: (controller, url) async {
// 加載完成
inAppWebViewController = controller;
print("加載地址:$url");
var html = await controller.getHtml();
debugPrint("html是:${html.toString().trim()}");
var dom = parse(html);
print("標題是:${dom.querySelector('.title')?.text}");
},
);
執(zhí)行腳本
要等頁面加載完成后才能執(zhí)行
// 執(zhí)行腳本
var body = await inAppWebViewController.evaluateJavascript(
source: "document.body.innerHTML");
debugPrint("執(zhí)行結(jié)果:${body.toString().trim()}");
遇到的問題
最開始我的想法是執(zhí)行函數(shù),然后更新要顯示的組件,但是resBody 一直沒有更新。后來發(fā)現(xiàn)好像是onLoadStop沒有執(zhí)行,仔細思考后應(yīng)該是InAppWebView初始化后,沒有在頁面上顯示導致后續(xù)方法沒有執(zhí)行。解決方法就是讓InAppWebView在頁面上顯示,當然可能不想在頁面顯示,這時給它父容器設(shè)置一個高度比如1,這樣就可以解決這個問題。
Future searchNovelFromWeb() async {
String html = '';
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse('https://onion.inscode.cc/')),
onLoadStop: (controller, url) async {
inAppWebViewController = controller;
print("開始搜索了");
html = await inAppWebViewController.getHtml() ?? '1111';
debugPrint("查詢的值:${html.toString()}");
setState(() {
resBody = const Text("搜索完成");
});
},
);
}
柚子快報邀請碼778899分享:flutter:webview
精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。