在加载之前,React-native android WebView句柄单击了Url [英] React-native android WebView handle clicked Url before loading

查看:63
本文介绍了在加载之前,React-native android WebView句柄单击了Url的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过反应原生的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆