Как я могу наложить собственный вид поверх PhoneGap CordovaWebView на Android?
Я создаю плагин phonegap, который должен отображать собственный пользовательский интерфейс поверх WebView, который предоставляет PhoneGap. В iOS это очень просто, просто создайте представление и добавьте его в прокрутку экрана PhoneGap webView. Это приведет к управлению над webView и позволит ему прокручивать содержимое HTML (обратите внимание, что в этом примере используется UIButton, но я буду применять его к настраиваемому элементу управления пользовательским интерфейсом):
-(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?
Ответы
Ответ 1
С помощью Cordova Android 4.0.2 мне удалось добавить представление поверх веб-представления, например:
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, но для моего проекта мне это не нужно.
Ответ 2
Поэтому я провожу некоторое время на этом сам, мое решение имеет несколько частей:
- У вас есть ваш CordovaWebView в вашем макете XML
- Ваша деятельность расширяет возможности 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, чтобы вернуть собственный экземпляр CordovaWebView из XML.
Метод 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" />
Ответ 3
Вы пытались увидеть порядок своих просмотров?
Возможно, это перекрыло ваш веб-просмотр
//скрыть веб-просмотр
//webview.setVisibility(View.GONE);//чтобы проверить, Появится новый вид webview.setZOrderOnTop(истина);
//показать новое представление myView.setVisibility(View.VISIBLE);
myView.bringToFront();
Я буду считать, что вы на 100% уверены, что эта строка получит действительный родитель, который вы можете добавить.
FrameLayout frameLayout = (FrameLayout). WebView.getParent() GetParent();