嗨,我有以下情況之前點擊網址:陣營 - 原生Android的WebView手柄裝入
我展示一個網站低谷反應原生一個的WebView。在此網站上有一個指向PassWallet(.pkpass)文件的鏈接(不是唯一的用例)。當我點擊本網站上的任何鏈接時,我想檢查它是否是其他網站或.pkpass文件或其他。雖然此檢查正在運行,但我不想加載任何內容,只需等到我的功能完成後,我就知道是否應打開網站或打開其他應用或其他內容。我想在JavaScript方面做到這一點,因爲我的整個路由功能在那裏,我認爲react-native是爲這種情況建立的:-)
在iOS上有這個美麗的功能onShouldStartLoadWithRequest
正是我所需要的。
_onShouldStartLoadWithRequest(e) {
if(checkUrl(e.url)) {
let Router = this.props.navigator.props.router;
let route = Router.getRouteFromUrl(e.url);
this.props.navigator.push(route);
return false;
}
return true;
}
我收到事件(e)並可以檢查它試圖加載的網址。我甚至可以用e.navigationType檢查它是否是點擊或其他。
現在在Android上這個功能不存在。在本機端有功能shouldOverrideUrlLoading
,但是這個功能沒有在react-native中實現。 我發現下面的GitHub問題/ PR https://github.com/facebook/react-native/pull/6478 我想現在,因爲這個問題是封閉的,因此有解釋,這個函數不能實現。
所以我開始自己找一個方法。我創建了一個顯示WebView的Native UI組件,然後實現此方法。
CustomWebViewManager.java:
package ch.mypackage;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
public class CustomWebViewManager extends SimpleViewManager<CplusWebView> {
@Override
public String getName() {
return "CplusWebView";
}
@Override
protected CustomWebView createViewInstance(ThemedReactContext reactContext) {
return new CustomWebView(reactContext);
}
@ReactProp(name = "url")
public void setUrl(CustomWebView view, @Nullable String url) {
view.loadUrl(url);
}
@ReactProp(name = "javascriptEnabled")
public void setJavascriptEnabled(CustomWebView view, boolean enabled) {
view.getSettings().setJavaScriptEnabled(enabled);
}
}
CustomWebView.java
package ch.couponplus;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.RCTEventEmitter;
public class CustomWebView extends WebView {
EventDispatcher eventDispatcher;
EventWebClient eventWebClient;
public CustomWebView(ThemedReactContext reactContext) {
super(reactContext);
eventWebClient = new EventWebClient();
setWebViewClient(eventWebClient);
}
protected class EventWebClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(),
"topChange",
event);
return true;
}
}
}
它將按預期工作。我現在可以觸發JS中的shouldOverrideUrlLoading
函數並創建日誌或其他內容。
但我的問題是,我現在如何在Javascript中設置true
或false
來控制我的shouldOverrideUrlLoading
函數?有沒有可能讓我自己的功能可用?到目前爲止,我只能設法觸發onChange
事件?
我只是想和我在iOS中做的一樣:-(也許有人出現並告訴我這是不可能的,無論出於何種原因,但我該怎麼處理或者如何處理這種情況?知道有URL模式,但這麼多,我知道他們不會在這種情況下工作。
我很感激在這一個任何幫助....
謝謝您的回答。這是一個非常好的解決方案,我在其他情況下使用它,例如有鏈接時,我希望它在我自己的視圖中打開,而不是在瀏覽器中打開。但是如果你想打開一個不是像.pkpass文件那樣的網頁的鏈接,應用程序會崩潰,因爲它開始加載鏈接,然後才能停止它。使用iOS功能,您可以在執行任何操作之前停止請求。至於我可以測試這種情況'onNavigationStateChange'在第一次加載請求後被調用。或者當您點擊無效鏈接時,您是否找到了停止加載的方法? – vanBrunneren
我能想到解決這個問題的唯一方法就是停止使用'stopLoading'函數加載webview。但是接下來你會說'onNavigationStateChage'在加載請求後被調用,所以在調用'stopLoading()'的時候 - 可能已經太晚了,應用程序會崩潰。 但我會嘗試一次,看看上面的解決方案是否工作。 –
我不能確切地說哪個函數會在哪個時間被調用,但我可以看到應用程序崩潰之前,我可以停止它,只要我想打開一個像.pkpass一樣的鏈接 – vanBrunneren