通过重写cocos2d::ui::EditBox的keyboardWillShowkeyboardWillHide方法可以监听键盘高度。

在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);
    }
}


Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐