【发布时间】:2016-12-24 06:44:13
【问题描述】:
我正在通过 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) 并且可以检查它尝试加载的 url。我什至可以检查 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 模式,但我知道它们在这种情况下不起作用。
【问题讨论】:
标签: javascript android reactjs webview react-native