最近遊戲接入了一個私服平臺,因爲沒有sdk,因此支付相關的操做須要在網頁端進行,也就是說點擊充值須要在遊戲內部彈出一個網頁,並定位到平臺充值的地址。查閱相關資料後決定使用cocos2dx自帶的WebView來完成這項任務。WebView的使用方式很是簡單,代碼以下:java
#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,返回遊戲。ide
首先監聽遊戲內部返回鍵,並處理返回鍵邏輯:函數
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的返回鍵事件觸發時,直接調用遊戲主界面的事件監聽函數,並禁止事件向下傳遞。ui