在android中是否有任何方法可以获得设备虚拟键盘的高度

Zee*_*rza 37 sdk android

Android中是否有任何方法可以在运行时获取Android设备的虚拟键盘的高度.其实我想在键盘上方显示文本框.

小智 47

为了解决这个问题,我编写了一个keyboardHeightProvider,它可以计算浮动软键盘的高度.可以在AndroidManifest.xml中将Activity设置为adjustNone或adjustPan.

https://github.com/siebeprojects/samples-keyboardheight

希比

  • adjustNOTHING唯一可行的解​​决方案! (7认同)
  • 做得好!它可以使用,因为windowSoftInputMode 是adjustNothing。 (3认同)
  • 此代码无法在带有缺口的手机上正常工作,我的高度不正确... (2认同)

Dav*_*nce 38

我为此尝试了许多建议的方法,但似乎没有一个适用于Android SDL.我认为这是因为SDL显示是"全屏"或者它位于"AbsoluteLayout"内,因此"视图"的高度从未实际改变.这个方法对我有用:

获得软键盘的尺寸

mRootWindow = getWindow();
mRootView = mRootWindow.getDecorView().findViewById(android.R.id.content);
mRootView.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {
    public void onGlobalLayout(){
        Rect r = new Rect();
        View view = mRootWindow.getDecorView();
        view.getWindowVisibleDisplayFrame(r);
        // r.left, r.top, r.right, r.bottom
    }
    });
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答,正是我所需要的.这适用于计算屏幕键盘大小而不使用adjustResize(我不想要). (4认同)
  • 不适用于"adjustNothing" (3认同)
  • 就我而言:int heightDiff = mRootView.getHeight()-r.bottom; 工作正常 (2认同)

Tec*_*ist 32

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

  1. 获取布局的根视图
  2. 获取此根的Viewtree观察者,并在此基础上添加全局布局侦听器.

现在,无论何时显示软键盘,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.  
        }
  });
Run Code Online (Sandbox Code Playgroud)

此致,Techfist

  • 我认为这只适用于android:windowSoftInputMode ="adjustResize" (26认同)
  • 这只是得到键盘是否显示,但它不会给你键盘的高度. (3认同)

Jan*_*ier 17

2022年解决方案

使用新的Window insets api 就非常简单了:

WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(activity.getWindow().getDecorView());
//Enjoy your keyboard height
int keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
Run Code Online (Sandbox Code Playgroud)

您还可以轻松监听键盘显示/隐藏事件:

ViewCompat.setOnApplyWindowInsetsListener(activity.getWindow().getDecorView(), (v, insets) -> {
   boolean isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
   int keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
   
   //Do your job here

   return insets;
});
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多内容。


Pie*_*rre 9

此方法适用于adjustNothingwindowSoftInputMode的活动。

<activity android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:theme="@style/AppTheme"
        android:windowSoftInputMode="stateHidden|adjustNothing"/>
Run Code Online (Sandbox Code Playgroud)

使用 a PopupWindow,您可以为其设置单独的“键盘行为”,它会通知您键盘的大小。PopupWindow具有屏幕的高度,但宽度为0px,因此您不会看到它,它不会影响您的活动,但会为您提供所需的信息。

创建一个名为的类KeyboardHeightProvider并添加以下代码:

public class KeyboardHeightProvider extends PopupWindow {
    public KeyboardHeightProvider(Context context, WindowManager windowManager, View parentView, KeyboardHeightListener listener) {
        super(context);

        LinearLayout popupView = new LinearLayout(context);
        popupView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        popupView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            DisplayMetrics metrics = new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(metrics);

            Rect rect = new Rect();
            popupView.getWindowVisibleDisplayFrame(rect);

            int keyboardHeight = metrics.heightPixels - (rect.bottom - rect.top);
            int resourceID = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceID > 0) {
                keyboardHeight -= context.getResources().getDimensionPixelSize(resourceID);
            }
            if (keyboardHeight < 100) {
                keyboardHeight = 0;
            }
            boolean isLandscape = metrics.widthPixels > metrics.heightPixels;
            boolean keyboardOpen = keyboardHeight > 0;
            if (listener != null) {
                listener.onKeyboardHeightChanged(keyboardHeight, keyboardOpen, isLandscape);
            }
        });

        setContentView(popupView);

        setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
        setWidth(0);
        setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        setBackgroundDrawable(new ColorDrawable(0));

        parentView.post(() -> showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0));
    }

    public interface KeyboardHeightListener {
        void onKeyboardHeightChanged(int keyboardHeight, boolean keyboardOpen, boolean isLandscape);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意 PopupWindow 如何拥有自己的setSoftInputMode(...),因此无论您将 Activity 设置为什么,PopupWindow 仍然会受到键盘打开或关闭的影响,并将提供父 Activity 的高度。如果高度是,>= 100您可以假设键盘是打开的。

要使用它,只需在 Activity 的onCreate(...)方法中实例化它setContentView(...)

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    LinearLayout llRoot = findViewById(R.id.llRoot); //The root layout (Linear, Relative, Contraint, etc...)

    new KeyboardHeightProvider(this, getWindowManager(), llRoot, new KeyboardHeightProvider.KeyboardHeightListener() {
        @Override
        public void onKeyboardHeightChanged(int keyboardHeight, boolean keyboardOpen, boolean isLandscape) {
            Log.i("keyboard listener", "keyboardHeight: " + keyboardHeight + " keyboardOpen: " + keyboardOpen + " isLandscape: " + isLandscape);

            //Do what you want or have to with the parameters..
        }
    });

    //...
}
Run Code Online (Sandbox Code Playgroud)


nul*_*ter 7

将文本框作为父级底部.

android:layout_alignParentBottom="true"
Run Code Online (Sandbox Code Playgroud)

并在清单文件中进行软输入 adjustresize

android:windowSoftInputMode="adjustResize"
Run Code Online (Sandbox Code Playgroud)

然后当键盘出现时,文本框将向上移动.

  • 我有一个全屏视频视图,当调整布局大小时,我不想移动视频视​​图,但是我仍然希望文本框移动并保持在键盘上方。一个人如何做到这一点? (2认同)

cta*_*ate 5

You can't tell. No, really: you simply can't tell.

键盘不需要是任何特定的形状。它没有被放置在屏幕的底部(许多最流行的选项都没有),它没有当您更改文本字段(几乎没有不取决于标志),以保持其目前的规模。它甚至不必是矩形的。它也可能只是接管整个屏幕

(我对类似问题的回答的副本,获取软键盘的尺寸