最近进入了一个第三方的api游戏,需要自定义一个返回按钮,来作为退出游戏的逻辑处理,刚开始的是使用cocos2d Button控件,像平时那样调整层级或者ZOrder,但是无论设置多高,Webview都始终在最上层。原来WebView是系统的原生的控件,属于手机原生层,而cocos2d的都在OPGL层,所以我们必须去修改原生代码才行。也就是引擎中UIWebViewImpl-ios.mm 以UIWebViewImpl-android.cpp 这两个文件。
首先我们来处理Android:
打开之后发现UIWebViewImpl-android.cpp只是提供调用接口,具体的实现是"org/cocos2dx/lib/Cocos2dxWebViewHelper"这个类中:找到createWebView()方法,然后在里面增加android 原生Button控件:
public static int createWebView() {
final int index = viewTag;
sCocos2dxActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
final Cocos2dxWebView webView = new Cocos2dxWebView(sCocos2dxActivity, index);
Button backButton = new Button(sCocos2dxActivity);//新增的按钮
backButton.setBackgroundResource(R.drawable.btn_chat_close);//按钮资源路径
backButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
backButton.setOnClickListener(new OnClickListener() {//按钮回调
@Override
public void onClick(View view) {
Log.i("backButtononClick", "backButtononClick");
AlertDialog.Builder builder = new AlertDialog.Builder(sCocos2dxActivity); //先得到构造器
builder.setTitle("提示"); //设置标题
builder.setMessage("是否确认退出?"); //设置内容
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { //设置确定按钮
@Override
public void onClick(DialogInterface dialog, int which) {
closeThirdGame();//回调cocos的函数逻辑处理
dialog.dismiss(); //关闭dialog
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { //设置取消按钮
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
});
webView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
Cocos2dxGLSurfaceView.getInstance().requestFocus();
return true;
}
}
else {
Cocos2dxGLSurfaceView.getInstance().requestFocus();
}
return false;
}
});
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
webView.addView(backButton);//按钮直接增加到webview上面
sLayout.addView(webView, lParams);
webViews.put(index, webView);
}
});
return viewTag++;
}
ios处理:
打开UIWebViewImpl-ios.mm找到webview创建方法setupWebView(),增加ios原生按钮控件到上面就好了
@interface UIWebViewWrapper () <UIWebViewDelegate>
@property(nonatomic, retain) UIWebView *uiWebView;
@property(nonatomic, retain) UIButton *backButton; //增加按钮申明
@property(nonatomic, copy) NSString *jsScheme;
@end
@implementation UIWebViewWrapper {
}
+ (instancetype)webViewWrapper {
return [[[self alloc] init] autorelease];
}
- (instancetype)init {
self = [super init];
if (self) {
self.uiWebView = nil;
self.backButton = nil;//初始化
self.shouldStartLoading = nullptr;
self.didFinishLoading = nullptr;
self.didFailLoading = nullptr;
}
return self;
}
- (void)dealloc {
self.uiWebView.delegate = nil;
[self.uiWebView removeFromSuperview];
self.uiWebView = nil;
[self.backButton removeFromSuperview];//析构
self.backButton = nil;
self.jsScheme = nil;
[super dealloc];
}
- (void)setupWebView {
if (!self.uiWebView) {
self.uiWebView = [[[UIWebView alloc] init] autorelease];
self.uiWebView.delegate = self;
}
if (!self.backButton) {//ios按钮创建
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backButton setFrame:CGRectMake(0, 5, 57, 57)];
[self.backButton setImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
self.backButton.showsTouchWhenHighlighted = NO;
[self.backButton addTarget:self action:@selector(onPressEnd) forControlEvents:UIControlEventTouchUpInside];//自定义按钮回调
}
if (!self.uiWebView.superview) {
auto view = cocos2d::Director::getInstance()->getOpenGLView();
auto eaglview = (CCEAGLView *) view->getEAGLView();
[eaglview addSubview:self.uiWebView];
}
if (!self.backButton.superview) { //添加
[self.uiWebView addSubview:self.backButton];
}
}
这只是一个添加简单的按钮,为大家修改Webview控件提供一个可行的思路,如果需要增加很多其他各种控件,最好新增一个管理类来集中处理