我如何在Android上获得软键盘高度?

时间:2013-09-23 04:09:54

标签: android libgdx android-softkeyboard

我一直在使用libgdx开发一个Android项目。期间发生了一个问题。当软键盘出现时,会覆盖一些视图,所以我想获得解决这个bug的高度。

我知道有一个软输入模式可以设置解决这个问题,当使用android api开发项目时,libgdx提供了什么方式?

2 个答案:

答案 0 :(得分:0)

是的,您可以在Viewtree Observer和全局布局监听器的帮助下,尝试下面提到的步骤

  1. 获取布局的根视图
  2. 获取此根的Viewtree观察者,并在此基础上添加全局布局侦听器。
  3. 现在无论何时显示软键盘,android都会重新调整屏幕大小,您将收到听众的电话。这就是你现在唯一需要做的就是计算你的根视图在重新调整大小和原始大小之后的高度之间的差异。如果差异超过150则认为这是因为键盘已经膨胀。

    以下是示例代码

    root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
         public void onGlobalLayout(){
               int heightDiff = root.getRootView().getHeight()- root.getHeight();
               // IF height diff is more then 150, consider keyboard as visible.  
            }
      });
    

答案 1 :(得分:0)

我有一个工作解决方案,我想分享。

首先,没有办法从libgdx api中获得软键盘高度。您必须编写特定于平台的代码。与平台特定代码接口相当简单 - 不用担心! Read this guide from the official libgdx wiki

以下代码是原生的android代码,应该放在libgdx android gradle模块中:

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import com.badlogic.gdx.backends.android.AndroidApplication;

/**
 * Container for platform-specific android implementation.
 */
public class PlatformSpecificAndroidImpl implements PlatformSpecificService {
    private AndroidApplication androidApplication;
    private AndroidGlobalLayoutListener globalLayoutListener;

    public PlatformSpecificAndroidImpl(AndroidApplication androidApplication) {
        this.androidApplication = androidApplication;
    }

    /**
     * Initialize platform services. This method should be called from the gdx applications "create()" method.
     */
    @Override
    public void init() {
        globalLayoutListener = new AndroidGlobalLayoutListener(androidApplication);
        Window window = androidApplication.getWindow();
        if (window != null) {
            View decorView = window.getDecorView();
            if (decorView != null) {
                View rootView = decorView.getRootView();
                if (rootView != null) {
                    ViewTreeObserver viewTreeObserver= rootView.getViewTreeObserver();
                    if (viewTreeObserver != null) {
                        viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener);
                    }
                }
            }
        }
    }

    /**
     * Get the window height that is really usable, subtracting the soft-keyboard if open.
     * @return usable window height
     */
    @Override
    public int getUsableWindowHeight() {
        if (globalLayoutListener != null) {
            return globalLayoutListener.getHeight();
        }
        return 0;
    }

    private static class AndroidGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
        private AndroidApplication androidApplication;
        private int height;

        private AndroidGlobalLayoutListener(AndroidApplication androidApplication) {
            this.androidApplication = androidApplication;
        }

        @Override
        public void onGlobalLayout() {
            height = 0;
            Window window = androidApplication.getWindow();
            if (window != null) {
                View currentFocus = window.getCurrentFocus();
                if (currentFocus != null) {
                    View rootView = currentFocus.getRootView();
                    if (rootView != null) {
                        Rect rect = new Rect();
                        rootView.getWindowVisibleDisplayFrame(rect);
                        height = rect.bottom;
                    }
                }
            }
        }

        public int getHeight() {
            return height;
        }
    }
}

从libgdx核心模块中,您现在可以通过PlatformSpecificService接口调用方法getUsableWindowHeight()。它返回显示高度(以像素为单位)减去软键盘高度。

为什么我在使用OnGlobalLayoutListener并且在请求时不直接在getter方法中计算高度?好吧,在我的选择中,这是一种稍微优雅的解决方案。

还有一点需要注意: 通过Gdx.input.setOnscreenKeyboardVisible(true);打开软键盘涉及异步通信。如果您碰巧在setOnscreenKeyboardVisible之后直接调用getUsableWindowHeight(),您仍将获得完整的显示高度,因为键盘尚未实际打开。