【问题标题】:How can I overlay a native view on top of PhoneGap's CordovaWebView in Android?如何在 Android 中的 PhoneGap 的 CordovaWebView 之上覆盖原生视图?
【发布时间】:2013-10-22 18:10:12
【问题描述】:

我正在构建一个 phonegap 插件,它需要在 PhoneGap 提供的 WebView 之上呈现原生 UI 视图。在iOS 中这很简单,只需创建视图并将其添加到PhoneGap 的webView 的scrollView 中。这将在 webView 顶部呈现控件并允许它随着 HTML 内容滚动(请注意,此示例使用 UIButton,但我会将其应用于自定义 UI 控件):

-(void)createNativeControl:(CDVInvokedUrlCommand *)command
{
    NSDictionary* options = [command.arguments objectAtIndex:0];
    NSNumber* x = [options objectForKey:@"x"];
    NSNumber* y = [options objectForKey:@"y"];
    NSNumber* width = [options objectForKey:@"width"];
    NSNumber* height = [options objectForKey:@"height"];

    CGRect rect = CGRectMake([x floatValue], [y floatValue], [width floatValue], [height floatValue]);
    self._nativeControl = [UIButton buttonWithType:UIButtonTypeSystem];
    self._nativeControl.frame = rect;

    [self._nativeControl addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self._nativeControl setTitle:@"Click me" forState:UIControlStateNormal];
    [self.webView.scrollView addSubview:self._nativeControl];

    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    [self.commandDelegate sendPluginResult:result callbackId:command.callbackID];
}

我尝试在 Android 中做一些大致相同的事情,但没有成功。这是我最近的尝试:

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    System.out.println(String.format("%s action called", action));

    if ("echo".equals(action)) {
        String message = args.optString(0);
        this.echo(message, callbackContext);
        return true;
    } else if ("createNativeControl".equals(action)) {
        this.createNativeControl(callbackContext);
        return true;
    }

    return false;
}

private void createNativeControl(CallbackContext callbackContext) {
    // Find the frame layout parent and place the control on top - theoretically
    // this should appear on TOP of the webView content since the TextView child is
    // added later
    FrameLayout frameLayout = (FrameLayout) webView.getParent().getParent();

    TextView view = new TextView(frameLayout.getContext());
    view.setText("Hello, Android!");
    view.setVisibility(View.VISIBLE);

    frameLayout.addView(view, 100,100);
    callbackContext.success();
}

如何在 Android 中完成此操作?

【问题讨论】:

  • 如何获得 self.webView.scrollView?你声明了吗?

标签: android cordova phonegap-plugins


【解决方案1】:

使用 Cordova Android 4.0.2,我能够在 webview 顶部添加一个视图,如下所示:

public class HVWMaps extends CordovaPlugin {

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {

        FrameLayout layout = (FrameLayout) webView.getView().getParent();

        TextView textView = new TextView(layout.getContext());
        textView.setBackgroundColor(Color.BLUE);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(500, 500);
        params.setMargins(100, 100, 100, 100);
        textView.setLayoutParams(params);
        layout.addView(textView);
    }
}

CordovaWebView 的界面最近似乎发生了变化,所以这可能不适用于旧版本。对于此示例,您还需要将 <param name="onload" value="true" /> 添加到 plugin.xml 中的功能,以便调用 initialize(..)

<platform name="android">
    <config-file target="res/xml/config.xml" parent="/*">
        <feature name="YourPlugin" >
            <param name="android-package" value="com.your.plugin"/>
            <param name="onload" value="true" />
        </feature>
    </config-file>
</platform>

这不会像你提到的 iOS 那样随 webview 滚动,但对于我的项目我不需要它。

【讨论】:

  • 我刚刚用 5.1.0 尝试了上述方法,我可以让它工作
  • 您是否还可以考虑滚动 web 视图?
  • 我需要在某些事件上添加按钮。当我在“执行”方法下执行此代码时,它会抛出异常说..只有创建视图的原始线程才能添加视图。
【解决方案2】:

所以我自己花了一些时间,我的解决方案有多个部分:

  • 您的布局 XML 中有您的 CordovaWebView
  • 您的 Activity 扩展了 CordovaActivity
  • 你重写了几个方法:

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_page);
    super.init();
    loadUrl("file://" + getFilesDir()+"index.html");
    
    ....and other code you like...
    }
    
    
     @Override
        protected CordovaWebView makeWebView() {
            SystemWebViewEngine systemWebViewEngine =
            new SystemWebViewEngine((SystemWebView) findViewById(R.id.cordovaWebView));
    return new CordovaWebViewImpl(systemWebViewEngine);
        }
    
        @Override
        protected void createViews() {
    //must override this, otherwise crash
    if (preferences.contains("BackgroundColor")) {
        int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK);
        // Background of activity:
        appView.getView().setBackgroundColor(backgroundColor);
    }
            appView.getView().requestFocusFromTouch();
        }
    

所以 makeWebView() 是关键部分,您可以在其中覆盖 CordovaActivity 的方法以从 XML 返回您自己的 CordovaWebView 实例。

createViews() 方法也必须被覆盖,因为如果您检查 CordovaActivity 代码,就会有一个 setContentView(appView.getView()),否​​则会导致崩溃。您确保在覆盖时删除该部分。

最后是xml(不是全部内容):

    <!-- The main content view -->
    <org.apache.cordova.engine.SystemWebView
    android:id="@+id/cordovaWebView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

【讨论】:

  • 我尝试了很多方法,甚至使用 java 代码。最后你的解决方案对我有用。谢谢@Karoly !!
【解决方案3】:

您是否尝试过查看视图的顺序? 也许它与您的 webview 重叠

//隐藏网页视图
//webview.setVisibility(View.GONE); //测试是否 新视图出现
webview.setZOrderOnTop(true);

//显示新视图 myView.setVisibility(View.VISIBLE);

myView.bringToFront();

我假设你 100% 确定这条线有一个有效的父级,你可以添加一个视图。

FrameLayout frameLayout = (FrameLayout) webView.getParent().getParent();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多