我正在通过 react-native 中的 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 的本机 UI 组件,然后实现了这个方法。
自定义WebViewManager.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);
}
}
自定义WebView.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;
}
}
}
它按预期工作。我现在可以shouldOverrideUrlLoading
在 JS 中触发该功能并制作日志或其他任何东西。
但我的问题是我现在如何设置true
或false
在 Javascript 中控制我的shouldOverrideUrlLoading
功能?是否有可能使我自己的功能可用?直到现在我才设法触发onChange
事件?
我只想做出与我在 iOS 中所做的相同的事情。也许有人过来告诉我无论出于何种原因这是不可能的,但是我应该如何或您如何处理这样的情况?我知道有 Url 模式,但我知道它们在这种情况下不起作用。