通过重写cocos2d::ui::EditBox的keyboardWillShow和keyboardWillHide方法可以监听键盘高度。
在iOS平台能实现该功能,但是android平台上运行却不是我们想要的结果,还是键盘弹起时,整个界面往上移动。
通过打印日志,发现EditBoxView重写的keyboardWillShow和keyboardWillHide方法没有被执行,这样就不能监听键盘高度变化。如果想要实现这个功能我们只能修改部分源代码。
找到Cocos2dxEditBoxHelper.java文件,如图:
在73行左右后面添加如下代码:
private static native void keyboardVisibleChanged(int width, int height);
public static void __keyboardVisibleChanged(int width, int height){
keyboardVisibleChanged(width, height);
}
public void observeSoftKeyboard() {
final View decorView = mCocos2dxActivity.getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
int keyboardState = -1;
int minKeyboardHeight = 0;
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
int keyboardHeight = decorView.getHeight() - (rect.bottom - rect.top);
boolean hidden = ((double) keyboardHeight / decorView.getHeight()) < 0.2;
int state = hidden ? 1 : 0;
if (keyboardState != state) {
int height = 0;
if (state == 1) {
minKeyboardHeight = keyboardHeight;
} else {
height = keyboardHeight - minKeyboardHeight;
}
final int mWidth = decorView.getWidth();
final int mHeight = height;
mCocos2dxActivity.runOnGLThread(new Runnable() {
@Override
public void run() {
Cocos2dxEditBoxHelper.__keyboardVisibleChanged(mWidth, mHeight);
}
});
keyboardState = state;
}
}
});
}
在
public
Cocos2dxEditBoxHelper(ResizeLayout
layout
)函数中添加如下代码:
public Cocos2dxEditBoxHelper(ResizeLayout layout) {
Cocos2dxEditBoxHelper.mFrameLayout = layout;
Cocos2dxEditBoxHelper.mCocos2dxActivity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
Cocos2dxEditBoxHelper.mEditBoxArray = new SparseArray<Cocos2dxEditBox>();
// 监听键盘高度
observeSoftKeyboard();
}
打开cocos2d/cocos/ui/UIEditBox/UIEditBoxImpl-android.cpp文件,添加如下代码:
static void editBoxEditingDidBegin(int index);
static void editBoxEditingDidChanged(int index, const std::string& text);
static void editBoxEditingDidEnd(int index, const std::string& text);
static void keyboardVisibleChanged(int width, int height);
extern "C"{
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxEditBoxHelper_editBoxEditingDidBegin(JNIEnv *env, jclass, jint index) {
editBoxEditingDidBegin(index);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxEditBoxHelper_editBoxEditingChanged(JNIEnv *env, jclass, jint index, jstring text) {
std::string textString = StringUtils::getStringUTFCharsJNI(env,text);
editBoxEditingDidChanged(index, textString);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxEditBoxHelper_editBoxEditingDidEnd(JNIEnv *env, jclass, jint index, jstring text) {
std::string textString = StringUtils::getStringUTFCharsJNI(env,text);
editBoxEditingDidEnd(index, textString);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxEditBoxHelper_keyboardVisibleChanged(JNIEnv *env, jclass, jint width, jint height) {
keyboardVisibleChanged(width, height);
}
}
void keyboardVisibleChanged(int width, int height)
{
auto winSize = cocos2d::Director::getInstance()->getWinSize();
float keyboardHeight = winSize.width * height / (float)width;
cocos2d::IMEKeyboardNotificationInfo notiInfo;
notiInfo.begin = cocos2d::Rect(0, 0, winSize.width, keyboardHeight);
notiInfo.end = cocos2d::Rect(0, 0, winSize.width, keyboardHeight);
notiInfo.duration = 0.25;
cocos2d::IMEDispatcher* dispatcher = cocos2d::IMEDispatcher::sharedDispatcher();
if (keyboardHeight == 0) {
dispatcher->dispatchKeyboardWillHide(notiInfo);
} else {
dispatcher->dispatchKeyboardWillShow(notiInfo);
}
}