溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Flutter WebView與JS如何互相調(diào)用

發(fā)布時間:2021-08-06 09:18:35 來源:億速云 閱讀:345 作者:小新 欄目:移動開發(fā)

小編給大家分享一下Flutter WebView與JS如何互相調(diào)用,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

WebView與JS互相調(diào)用是一個剛需,但是貌似現(xiàn)在大家寫的文章講的都不是很清楚,我這個簡易指南簡單粗暴地分為兩部分:JS調(diào)用Flutter和Flutter調(diào)用JS,拒絕花里胡哨,保證一看就懂,一學(xué)就會。

開始之前先簡單了解一下官方WebView所包含的API:

  • onWebViewCreated:在WebView創(chuàng)建完成后調(diào)用,只會被調(diào)用一次;

  • initialUrl:初始load的url;

  • javascriptMode:JS執(zhí)行模式(是否允許JS執(zhí)行);

  • javascriptChannels:JS和Flutter通信的Channel;

  • navigationDelegate:路由委托(可以通過在此處攔截url實現(xiàn)JS調(diào)用Flutter部分);

  • gestureRecognizers:手勢監(jiān)聽;

  • onPageFinished:WebView加載完畢時的回調(diào)。

JS調(diào)用Flutter

JS調(diào)用Flutter有兩種方法:使用javascriptChannels發(fā)送消息和使用路由委托(navigationDelegate)攔截url。

方法1:使用javascriptChannels發(fā)送消息

javascriptChannels參數(shù)可以傳入一組Channels,我們可以定義一個_alertJavascriptChannel變量,這個channel用來控制JS調(diào)用Flutter的toast功能:

JavascriptChannel _alertJavascriptChannel(BuildContext context) {
 return JavascriptChannel(
  name: 'Toast',
  onMessageReceived: (JavascriptMessage message) {
   showToast(message.message);
  });
 }

WebView(
 avascriptChannels: <JavascriptChannel>[
  _alertJavascriptChannel(context),
 ].toSet(),
;

在上面的代碼中,我們定義了一個_alertJavascriptChannel變量,并給它起了個name叫Toast,這個name屬性接收的是一個字符串,它代表了JS調(diào)用Flutter時,雙方共同商定好了的一個協(xié)議,JS通過這個name去post對應(yīng)的信息給Flutter(API為name.postMessage('xxxxxx'))。我們在網(wǎng)頁部分寫一個簡單的button,點擊后開始JS調(diào)用Flutter的邏輯:

<button onclick="callFlutter()">callFlutter</button>

function callFlutter(){
 Toast.postMessage("JS調(diào)用了Flutter");
}

onMessageReceived為Flutter接收到了JS的消息之后的回調(diào),我們可以通過message.message來獲取JS發(fā)給我們的消息內(nèi)容。JavascriptMessage類暫時只有一個String類型的message成員變量,所以如果需要傳遞復(fù)雜數(shù)據(jù),可以通過傳遞json字符串來解決。

代碼重點:JavascriptChannel中的name要與JS中的name.postMessage()相對應(yīng)??!

方法2:使用路由委托navigationDelegate攔截url

navigationDelegate回調(diào)在每次網(wǎng)頁路由地址發(fā)生變化的時候都會觸發(fā),因此我們可以攔截特定的url來實現(xiàn)JS調(diào)用Flutter。

同樣的,我們在網(wǎng)頁部分寫一個簡單的button,點擊后跳轉(zhuǎn)路由"js://webview?arg1=111&args2=222"。我們可以和客戶端協(xié)商好一個scheme,比如這個例子里面就是js://webview,我們可以在query string上帶上我們想要傳遞的參數(shù):

<button onclick="callFlutter()">callFlutter</button>

function callFlutter(){
 /*約定的url協(xié)議為:js://webview?arg1=111&arg2=222*/
 document.location = "js://webview?arg1=111&args2=222";
}

在Flutter端,我們就可以在navigationDelegate回調(diào)中攔截這個符合js://webviewscheme的路由地址了:

navigationDelegate: (NavigationRequest request) {
   if (request.url.startsWith('js://webview')) {
    showToast('JS調(diào)用了Flutter By navigationDelegate');
    print('blocking navigation to $request}');
    return NavigationDecision.prevent;
   }
   print('allowing navigation to $request');
   return NavigationDecision.navigate;
   },

我們通過return不同的值,告訴WebView怎么處理這個路由:

  • NavigationDecision.prevent:阻止路由替換;

  • NavigationDecision.navigate:允許路由替換。

Flutter調(diào)用JS

在WebView創(chuàng)建完成之后,我們可以拿到一個WebViewController,通過它的evaluateJavascript()方法,我們可以執(zhí)行JS語句:

onWebViewCreated: (WebViewController webViewController) {
 _controller = webViewController;
},
······
floatingActionButton: FloatingActionButton(
  onPressed: () {
   _controller
    ?.evaluateJavascript('callJS("visible")')
    ?.then((result) {
     // You can handle JS result here.
    });
  },
  child: Text('call JS'),
  ),
 <p id="p1" >
 Flutter 調(diào)用了 JS.
 Flutter 調(diào)用了 JS.
 Flutter 調(diào)用了 JS.
 </p>
 
function callJS(message){
 document.getElementById("p1").style.visibility = message;
}

在上面的例子中,我們點擊floatingActionButton后,就會去執(zhí)行JS中的callJS()方法了,具體UI體現(xiàn)為:將隱藏的段落重新顯示。evaluateJavascript()返回值是一個Future,因此我們可以接收JS給我們的返回值,返回值格式請閱讀官方API注釋。

這里要注意的是,evaluateJavascript()方法,F(xiàn)lutter建議我們在onPageFinished回調(diào)之后去執(zhí)行,以保證所有的HTML都已經(jīng)加載完畢了。因此在實際開發(fā)中,我這里展示的這種直接將onWebViewCreated中的controller賦值的方法是不可取的,應(yīng)該是使用FutureBuilder之類的方式去實現(xiàn)比較優(yōu)雅

看完了這篇文章,相信你對“Flutter WebView與JS如何互相調(diào)用”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI