React-native android WebView handle在加载前点击Url

React-native android WebView handle clicked Url before loading

本文关键字:Url 加载 android WebView handle React-native      更新时间:2023-09-26

我在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我想现在,因为这个问题已经结束了,因此有解释,这个函数没有实现。

所以我开始自己找办法。我创建了一个Native UI Component来显示WebView,然后实现这个方法。

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中设置truefalse来控制我的shouldOverrideUrlLoading函数?有可能让我自己的功能可用吗?到现在为止,我只触发了onChange事件?

我只是想和我在iOS中做的一样。也许有人过来告诉我,不管出于什么原因,这是不可能的但是我应该或者你怎么处理这样的情况?我知道有Url模式,但我知道它们在这种情况下不起作用。

我在react-native中通过WebView显示一个网站。在这网站上有一个PassWallet (.pkpass)文件的链接(不是唯一的用例)。当我点击本网站的任何链接时,我想检查一下无论是其他网站还是。pkpass文件或其他。

我也有类似的问题,我想检查在我的react-native应用程序的webView中点击的链接类型。就像你说的,在iOS方面的功能onShouldStartLoadWithRequest,这是不存在于Android方面。

这是我在Android端的解决方案。

   <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决定继续或停止并做其他事情。上面的解决方案是我在我们的应用程序中处理它的方式。

查看以下链接:

https://facebook.github.io/react-native/docs/webview.html stoploadinghttps://github.com/facebook/react-native/pull/6886

自2018年底以来,react-native-community/react-native-webview版本已支持onShouldStartLoadWithRequest。看到公关。