React本地:扩展WebView



(关于这个问题)

我想在React Native中创建一个组件,该组件具有与本机WebView完全相同的功能,只是覆盖了其一些方法。

我遵循了本机页面中的教程,带有模块和UI视图(我认为这是正确的方法),但我无法获得我想要的东西。

我能做的:

// .../com/project/permissionwebview/    
public class PermissionWebviewView extends LinearLayout{
    private Context context;
    public PermissionWebviewView(Context context) {
        super(context);
        this.context = context;
        init();
    }
    public void init() {
        inflate(this.context, R.layout.permissionwebview, this);
    }
}

和我的视图经理:

// .../com/project/permissionwebview
public class PermissionWebviewViewManager extends SimpleViewManager<PermissionWebviewView> {
    public static final String REACT_CLASS = "PermissionWebviewViewManager";
    @Override
    public String getName() {
        return REACT_CLASS;
    }
    @Override
    public PermissionWebviewView createViewInstance(ThemedReactContext context) {
        return new PermissionWebviewView(context); //If your customview has more constructor parameters pass it from here.
    }
}

布局的XML:

// .../res/layout/permissionwebview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <WebView android:id="@+id/permission_webview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
</LinearLayout>

我能够从React Antial称其为单位,但是什么也没有显示,什么也不会发生。

我想要的只是一个自定义元素,它称为本机一个(在这种情况下为 WebView),因此它呈现完全相同(相同的道具,相同的方法),在必要时仅覆盖其某些方法(在我的情况下,,onPermissionRequest())。

哪种方法是正确的方法?我如何(在哪里)调用父级/超级WebView?

编辑1

我认为我已经运行了,但是我不知道它是否是正确的方法,因为我仍然不知道如何传递所有参数反应本机组件(<PermissionWebview />)到本机WebView元素:

// .../com/project/permissionwebview/
public class PermissionWebviewView extends LinearLayout{
    private Context context;
    private WebView myWebView;
    public PermissionWebviewView(Context context) {
        super(context);
        this.context = context;
        init();
    }
    public void init() {
        inflate(this.context, R.layout.permissionwebview, this);
        myWebView = (WebView)findViewById(R.id.permission_webview);
        myWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onPermissionRequest(final PermissionRequest request) {
                request.grant(request.getResources());
            }
        });
        myWebView.loadUrl("https://staticWebSite.Until/Parameters/Are/Passed");
    }
}

谢谢!

我能够最终通过在github上的react-native-website repo中从Android上使用的扩展WebView来工作。此代码中有很多来自链接上的示例以及WebView的实际反应本机实现。

我计划提交一个带有一些更改的拉动请求,以便为了实际构建Java,还可以检索我包装的实际WebView所需的参考(并非每个人都需要此)。

请注意,某些类是嵌套的,而名称需要比GitHub的示例中的进一步资格:

这是我要做的。就我而言,我需要将应用程序缓存清单功能添加到WebView。您可能不需要所有这些导入语句,并且可能需要添加其他信息:

customwebviewmanager.java:

import android.os.Build;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.CookieManager;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.views.webview.WebViewConfig;
import com.facebook.react.views.webview.ReactWebViewManager;
@ReactModule(name = CustomWebViewManager.REACT_CLASS)
public class CustomWebViewManager extends ReactWebViewManager {
  protected static final String REACT_CLASS = "MyCustomWebView";
  protected static class CustomReactWebViewClient extends ReactWebViewManager.ReactWebViewClient { }
  protected static class CustomReactWebView extends ReactWebViewManager.ReactWebView {
    public CustomReactWebView(ThemedReactContext reactContext) {
      super(reactContext);
    }
  }
  public CustomWebViewManager() {
    mWebViewConfig = new WebViewConfig() {
      public void configWebView(WebView webView) {
      }
    };
  }
  public CustomWebViewManager(WebViewConfig webViewConfig) {
    mWebViewConfig = webViewConfig;
  }
  @Override
  public String getName() {
    return REACT_CLASS;
  }
  @Override
  protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContext) {
    return new CustomReactWebView(reactContext);
  }
  // I had to override this in order to enable my needed WebView functionality
  @Override
  protected WebView createViewInstance(ThemedReactContext reactContext) {
    ReactWebView webView = createReactWebViewInstance(reactContext);
    webView.setWebChromeClient(new WebChromeClient() {
      @Override
      public boolean onConsoleMessage(ConsoleMessage message) {
        if (ReactBuildConfig.DEBUG) {
          return super.onConsoleMessage(message);
        }
        // Ignore console logs in non debug builds.
        return true;
      }
      @Override
      public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
      }
    });
    reactContext.addLifecycleEventListener(webView);
    mWebViewConfig.configWebView(webView);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setDisplayZoomControls(false);
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setAppCacheMaxSize(1024*1024*8);
    webView.getSettings().setAllowFileAccess(true);
    webView.getSettings().setAppCacheEnabled(true);
    // not sure if the below is needed, but at least one post indicated that it was so I did this with my package name to be safe
    webView.getSettings().setAppCachePath("data/data/<your package name here>/cache");
    webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    webView.getSettings().setAllowFileAccessFromFileURLs(true);
    // Fixes broken full-screen modals/galleries due to body height being 0.
    webView.setLayoutParams(
            new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
    if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      WebView.setWebContentsDebuggingEnabled(true);
    }
    return webView;
  }
  @Override
  protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
    // Do not register default touch emitter and let WebView implementation handle touches
    view.setWebViewClient(new CustomReactWebViewClient());
  }
}

customwebviewpackage.java

  import java.util.Arrays;
  import java.util.Collections;
  import java.util.ArrayList;
  import java.util.List;
  import com.facebook.react.ReactPackage;
  import com.facebook.react.bridge.NativeModule;
  import com.facebook.react.bridge.ReactApplicationContext;
  import com.facebook.react.uimanager.ViewManager;
  public class CustomWebViewPackage implements ReactPackage {
      @Override
      public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Collections.emptyList();
      }
      @Override
      public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList(new CustomWebViewManager());
      }
  }

customwebview.jsx

  'use strict';
  import * as PropTypes from 'prop-types';
  import * as React from 'react';
  import {
    requireNativeComponent,
    WebView
  } from 'react-native';
  /**
   * Renders a native WebView via our custom wrapper. 
   * Necessary because the RN WebView does not turn on the App Cache functionality by default. 
   * Can't make this a .tsx file due to TS problems around spreading the this.props into the child WebView.
   */
  class CustomWebView extends React.Component {
    static propTypes = WebView.propTypes;
    render() {
      return (
        <WebView 
          {...this.props}
          ref={(view) => {
            this.props.wrappedRef(view);
          }}
          nativeConfig={{component: MyCustomWebView}} 
        />
      );
    }
  }
  const MyCustomWebView = requireNativeComponent('MyCustomWebView', CustomWebView, 
    WebView.extraNativeComponentConfig);
  export default CustomWebView;

注意wrappedRef属性。我添加了这一点,因为我的CustomWebView的消费者需要对实际渲染的WebView进行引用。这是由于它需要在那里参考功能,例如postMessage()。消费者通过箭头功能,该功能设置了对消费类中属性的引用。如您所见,该功能在传递给ref的内容中被调用。

相关内容

  • 没有找到相关文章