在加载之前,React-native android WebView句柄单击了Url [英] React-native android WebView handle clicked Url before loading
问题描述
我正在通过反应原生的WebView展示一个网站。在本网站上有一个PassWallet(.pkpass)文件的链接(不是唯一的用例)。当我点击本网站上的任何链接时,我想检查它是否是其他网站或.pkpass文件或其他什么。当这个检查正在运行时,我不想加载任何东西,只要等到我的功能完成,我就知道是否应该打开一个网站或打开另一个应用程序或其他什么。我想在JavaScript方面做这个,因为我的整个路由功能都在那里,在我看来本机是为这种情况而构建的: - )
I'm showing a Website trough a WebView in react-native. On this Website there is a link to a PassWallet (.pkpass) file (not the only use case). When I click on any link on this Website I want to check whether it is an other Website or a .pkpass file or whatever. While this check is running I don't want to load anything, just wait until my function is finished and I'm knowing if I should open a Website or open another app or whatever. I want to make this on the JavaScript side because my whole routing functions are there and in my opinion react-native was built for this cases :-)
在iOS上有这个漂亮的函数 onShouldStartLoadWithRequest
这正是我所需要的。
On iOS there is this beautiful function onShouldStartLoadWithRequest
which exactly does what I need.
_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检查它是否是点击或其他什么。
I'm getting the event (e) and can check what url it's trying to load. I can even check with e.navigationType if it was a click or whatever.
现在在Android上这个功能不存在。在本机端有函数 shouldOverrideUrlLoading
但是这个函数没有在react-native中实现。
我发现以下GitHub问题/ PR https://github.com/ facebook / react-native / pull / 6478
我现在想,因为这个问题已经关闭,因此有解释,这个功能没有实现。
Now on Android this function does not exists. On the native side there is the function shouldOverrideUrlLoading
but this function is not implemented in react-native.
I found the following GitHub issue / PR https://github.com/facebook/react-native/pull/6478
I guess now, because this issue is closed and there are explanations for therefore, this function don't get implemented.
所以我开始自己找路。我创建了一个显示WebView的Native UI组件,然后实现了这个方法。
So I started to find a way by myself. I created a Native UI Component which displays a WebView and then implement this method.
CustomWebViewManager.java:
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
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
函数并生成日志或其他内容。
It works as expected. I can now trigger the shouldOverrideUrlLoading
function in JS and make logs or whatever.
但我的问题是我现在如何设置 true
或 false
在Javascript中控制我的 shouldOverrideUrlLoading
函数?是否有可能使我自己的功能可用?到现在为止我只设法触发 onChange
事件?
But my question is how can I now set true
or false
in Javascript to control my shouldOverrideUrlLoading
function? And is there a possibility to make my own functions available? Until now I only managed to trigger the onChange
event?
我只想和我在iOS中做的一样。也许有人出现并告诉我,无论出于何种原因这是不可能的,但我应该怎么处理或如何处理这样的案件?我知道有Url架构,但我知道它们在这种情况下不起作用。
I just want to make the same as I made in iOS. Maybe someone comes up and tells me that this isn't possible for whatever reason but how should I or how do you handle cases like this? I know there are Url schemas but so much I know they don't work in this case.
推荐答案
我通过反应原生的WebView显示一个网站。在这个
网站上有一个指向PassWallet(.pkpass)文件的链接(不是唯一的
用例)。当我点击本网站上的任何链接时,我想检查
是否是其他网站或.pkpass文件或其他。
I'm showing a Website trough a WebView in react-native. On this Website there is a link to a PassWallet (.pkpass) file (not the only use case). When I click on any link on this Website I want to check whether it is an other Website or a .pkpass file or whatever.
我也有类似的问题,我想检查我的react-native应用程序的webView中点击的链接类型。就像你说的那样,在iOS端,函数 onShouldStartLoadWithRequest
,这在Android端不存在。
I had a similar issue as well, where I wanted to check the type of link clicked within the webView of my react-native app. Like you said, on the iOS side the function onShouldStartLoadWithRequest
, which is not present on the Android side.
这是我在Android方面的解决方案。
This was my solution on the Android side.
<WebView
source={{uri: this.props.url}}
onLoad={this.onLoad.bind(this)}
onShouldStartLoadWithRequest={this._onShouldStartLoadWithRequest}
onNavigationStateChange = {this._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);
this.refs[WEBVIEW_REF].stopLoading(); // <---- Add a similar line
//This will tell your webView to stop processing the clicked link
return false;
}
return true;
如果我正确理解您的问题,您需要一种方法来检查在WebView中单击的URL然后根据URL决定继续或停止并做其他事情。我在我们的应用程序中处理它的方式上面的解决方案。
If I understood your problem correctly, you want a way to check the URL clicked in your WebView and then decide based on the URL to proceed or stop and do something else. The solution above the way I handled it in our app.
查看以下链接:
https://facebook.github.io/react-native/docs/webview.html#stoploading
https://github.com/facebook/react-native/pull/6886
这篇关于在加载之前,React-native android WebView句柄单击了Url的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!