cocos2dx之WebView踩過的坑(android返回鍵處理問題)
阿新 • • 發佈:2017-07-25
lib mar 是否 12px blog tex clas ons 測試的
最近遊戲接入了一個私服平臺,由於沒有sdk,所以支付相關的操作需要在網頁端進行,也就是說點擊充值需要在遊戲內部彈出一個網頁,並定位到平臺充值的地址。查閱相關資料後決定使用cocos2dx自帶的WebView來完成這項任務。WebView的使用方式非常簡單,代碼如下:
#include "ui/CocosGUI.h"
using namespace cocos2d::experimental::ui; m_WebView = WebView::create(); // m_WebView為成員變量 m_WebView->setPosition(visibleSize / 2);
m_WebView->setContentSize(visibleSize);
m_WebView->loadURL("http://www.baidu.com");
m_WebView->setScalesPageToFit(true);
m_WebView->setOnShouldStartLoading([](WebView *sender, const std::string&url)
{
return true; }); m_WebView->setOnDidFinishLoading([](WebView *sender, const std::string&url)
{ }); m_WebView->setOnDidFailLoading([](WebView *sender, const std::string&url)
{
}); this->addChild(m_WebView);
是不是很簡單?但是在測試的時候卻出現了問題。彈出網頁之後,如果點擊返回鍵遊戲就會退出,分析之後發現是View處理返回鍵的默認操作是銷毀當前Activity。理想的效果是在彈出WebView之後,如果點擊返回鍵,先判斷網頁是否可返回,如果可返回就退到上一級網頁,如果不可返回(在最初的網頁),就關閉WebView,返回遊戲。
首先監聽遊戲內部返回鍵,並處理返回鍵邏輯:
bool FirstScene::init() { //註冊捕捉監聽 auto listenerkeyPad = EventListenerKeyboard::create(); listenerkeyPad->onKeyReleased = CC_CALLBACK_2(FirstScene::onKeyReleased, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerkeyPad, this); } void FirstScene::onKeyReleased(EventKeyboard::KeyCode keycode, cocos2d::Event *event) { if (keycode == EventKeyboard::KeyCode::KEY_BACKSPACE) { if (m_WebView) // 如果WebView正在顯示 { if (m_WebView->canGoBack()) // 判斷是否可返回到上一級網頁 { m_WebView->goBack(); } else { m_WebView->runAction(RemoveSelf::create()); // 關閉WebView m_WebView = nullptr; } } else // 如果處於遊戲主界面 { Director::getInstance()->popScene(); // 結束遊戲 } } }
接下來讓WebView彈出來時點擊返回鍵也執行上述邏輯,這要修改WebView源代碼,打開Cocos2dxWebView.java,路徑為:src/org/cocos2dx/lib/Cocos2dxWebView.java
public Cocos2dxWebView(Context context, int viewTag) { super(context); this.mViewTag = viewTag; this.mJSScheme = ""; this.setFocusable(true); this.setFocusableInTouchMode(true); this.getSettings().setSupportZoom(false); this.getSettings().setDomStorageEnabled(true); this.getSettings().setJavaScriptEnabled(true); // `searchBoxJavaBridge_` has big security risk. http://jvn.jp/en/jp/JVN53768697 try { Method method = this.getClass().getMethod("removeJavascriptInterface", new Class[]{String.class}); method.invoke(this, "searchBoxJavaBridge_"); } catch (Exception e) { Log.d(TAG, "This API level do not support `removeJavascriptInterface`"); } this.setWebViewClient(new Cocos2dxWebViewClient()); this.setWebChromeClient(new WebChromeClient()); this.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) // 返回鍵 { Cocos2dxGLSurfaceView.getInstance().onKeyDown(keyCode, KeyEvent) // 調用遊戲主界面的事件監聽函數 return true; // 攔截事件,禁止事件向下傳遞 } return false; // 其他事件不做處理,繼續傳遞 } }); }
其中Cocos2dxGLSurfaceView就是遊戲界面的View,當WebView的返回鍵事件觸發時,直接調用遊戲主界面的事件監聽函數,並禁止事件向下傳遞。
cocos2dx之WebView踩過的坑(android返回鍵處理問題)