Is there any way in Android to get the height of the virtual keyboard displayed on the device in run time? Actually I want to show a text box above the keyboard.
-
similar question [here](http://stackoverflow.com/questions/6009487/get-the-height-of-virtual-keyboard-in-android) :) – Oli May 28 '13 at 09:51
-
2but it was asked 2 years ago. May be there is some solution now. – Zeeshan Mirza May 29 '13 at 05:16
16 Answers
To solve this I have written a keyboardHeightProvider which can calculate the height of a floating soft keyboard. The Activity can be set to adjustNone or adjustPan in the AndroidManifest.xml.
https://github.com/siebeprojects/samples-keyboardheight
Siebe

- 671
- 6
- 3
-
-
Thanks for the solution. It would be great if you make lib out of it. – Maksim Ostrovidov Sep 10 '17 at 06:41
-
4This code doesnt work on phone with notch i am getting the wrong height... – Aman Verma Sep 30 '18 at 15:56
-
I thought this was working fine for so long, but then I noticed the height is wrong on Chromebooks in tablet mode :'( – 0101100101 Oct 22 '18 at 23:42
-
3Great work! It can use in that the windowSoftInputMode is adjustNothing. – Fantasy Fang Jan 09 '19 at 02:01
-
@Sniper, for phone with notch, you can try [this](https://stackoverflow.com/a/52063876/668963). – neevek Apr 28 '19 at 06:51
-
@vijay super late but, I dont think there is, you just have to see how it's used in the MainActivity of the project and copy the correct classes – mco Sep 12 '19 at 02:22
-
hi, does this lib support get keyboard height when app startup? Thanks – famfamfam Apr 14 '21 at 10:00
-
Hi just let other guys here know that this type of solution will not work always. There are lots of reasons this could not work, due to OS-specific API, spit mode, window mode, immersive mode or notch etc – AndroidEngineX Feb 09 '22 at 10:45
I tried many suggested methods for this, but none seemed to work for Android SDL. I think this is either because the SDL display is "full screen" or that it sits within an "AbsoluteLayout" and therefore the height of the "View" never actually changes. This method worked for me:
Getting the dimensions of the soft keyboard
Window mRootWindow = getWindow();
View 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
}
});

- 613
- 7
- 13

- 1,281
- 12
- 17
-
4Thanks for this answer, exactly what I needed. This works for calculating on-screen keyboard size without the adjustResize (which I don't want). – Alexey Yakovenko Feb 11 '15 at 21:15
-
1This is an excellent answer. @Dave Lawrence you should mention in the answer that it the Rect's height doesn't take into account the status bar. – Ari Nov 27 '15 at 11:42
-
1
-
3In my case : int heightDiff = mRootView.getHeight() - r.bottom; worked fine – Usman Rana Dec 12 '18 at 13:42
Yes you can, with the help of Viewtree Observer and global layout listener, just try below mentioned steps
- Get the root view of your layout
- get the Viewtree observer for this root, and add a global layout listener on top of this.
now whenever soft keyboard is displayed android will re-size your screen and you will receive call on your listener. That's it only thing you now need to do is calculate difference between height which your root view has after re-size and original size. If difference is more then 150 consider this as a keyboard has been inflated.
Below is a sample code
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.
}
});
Regards, Techfist

- 5,874
- 4
- 36
- 66

- 4,314
- 6
- 22
- 32
-
34i think this only works when android:windowSoftInputMode="adjustResize" – LiangWang Aug 28 '13 at 04:31
-
3this just gets whether or not the keyboard is shown, but it doesn't give you the height of the keyboard. – what is sleep Dec 06 '13 at 19:50
-
-
-
1150px is not enough for xxhdpi devices like the Nexus 5. Its better to convert this absolute pixel value from a dp value and use that instead. I use `120dp` and that works well for Nexus 7 (xhdpi) and Nexus 5 (xxhdpi). Your experiences may vary, though... – Thomas Keller Dec 01 '14 at 11:36
-
And `android:windowSoftInputMode="adjustResize" ` should be put in the AndroidMainfest's Activity attribution where your soft keyboard has been used. – zionpi May 26 '16 at 02:27
-
Doesn't work, some devices this code still > 0 when keyboard is not opened int heightDiff = rootLayout.getRootView().getHeight() - rootLayout.getHeight(); – Stevie Sep 06 '19 at 05:01
-
Just record the height before adding the observer. Then compare the value when it fires to the original value. If it is more, the keyboard is open and you can use heightDiff; if the same, the keyboard is closed. 150 is not a good guide, mine was 206 before adding the observer. – Casey Perkins Jul 10 '20 at 13:07
2022 solution
With a new Window insets api it is pretty simple:
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(activity.getWindow().getDecorView());
//Enjoy your keyboard height
int keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
You can also easily listen for keyboard show/hide events:
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;
});
Read more here.

- 534
- 4
- 13
-
1This is just perfect, except that it makes the Status Bar color disappear and turn white for some reason. Any solution to this problem? – Peter Jan 27 '23 at 13:11
-
On the top of Peter comment, the retrieved keyboard height also incorrect. From my naked eye, the returned value seems to be (actual keyboard height + status bar height) – Cheok Yan Cheng Feb 02 '23 at 11:21
-
@Peter I think you just need to update a few xml settings when using the new WindowInsets API. [See this](https://developer.android.com/develop/ui/views/layout/edge-to-edge) – zuko Apr 19 '23 at 14:40
-
@CheokYanCheng This setting affects the calculations: `WindowCompat.setDecorFitsSystemWindows(window, false)`. Irregardless, you can validate the keyboard height by getting the combined height of the top and bottom insets: `Insets.getInsets(WindowInsets.Type.navigationBars()).bottom`. There's other options for `WindowInsets.Type` too. – zuko Apr 19 '23 at 14:40
-
Nice work! But now a layout occupies whole height (bottom elements are behind navigation bar). You should customize insets before `return insets;`. – CoolMind Jun 19 '23 at 01:39
-
See also https://www.kodeco.com/18393648-window-insets-and-keyboard-animations-tutorial-for-android-11 for API 30+. – CoolMind Aug 01 '23 at 15:36
This method works with adjustNothing
or any windowSoftInputMode
on your activity.
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/AppTheme"
android:windowSoftInputMode="stateHidden|adjustNothing"/>
Using a PopupWindow
, you can have separate "keyboard behaviour" for it, and it will notify you what the size of the keyboard is. The PopupWindow has the height of the screen, but 0px width, so you won't see it, it won't affect your activity, but will provide you with the information you need.
Create a class called KeyboardHeightProvider
and add the following code:
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);
}
}
Notice how the PopupWindow has its own setSoftInputMode(...)
, so it doesn't matter what you set your activity to, the PopupWindow will still be affected by the keyboard opening or closing and will provide the parent activity of the height. If the height is >= 100
you can assume the keyboard is open.
To use it, simply instantiate it in your Activity's onCreate(...)
method after 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..
}
});
//...
}

- 8,397
- 4
- 64
- 80
-
1You haven't gotten enough credit for this. Dozens of articles and SO questions where people unsuccessfully try to make it work with `AdjustNothing`. This is it. Thanks. – Will Dec 01 '21 at 05:30
-
I had extra space above the keyboard, subtract `resourceID` fixed the problem. – adwardwo1f Apr 12 '22 at 04:20
-
1This works but I'm getting a memory leak warning when rotating the device. I was able to remove that by calling `dismiss` on the `PopupWindow` in `onPause` of my `Activity` – tagy22 Feb 13 '23 at 12:27
put the text box as parent bottom.
android:layout_alignParentBottom="true"
and in the manifest file make the soft input adjustresize
android:windowSoftInputMode="adjustResize"
then the text box will move up when the keyboard appears.

- 5,874
- 4
- 36
- 66
-
2I have a video view that is full screen that I do NOT want to move when the layout resizes, but I still want the text box to move and stay above the keyboard. How would one accomplish that? – Lo-Tan May 17 '15 at 20:38
-
@Lo-Tan this is exactly what I want to achieve as well. Did you figure out how to do it? – pesho Feb 04 '16 at 09:19
You can't tell. No, really: you simply can't tell.
The keyboard does not need to be any particular shape. It does not have to be placed at the bottom of the screen (many of the most popular options are not), it does not have to keep its current size when you change text fields (almost none do depending on the flags). It does not even have to be rectangular. It may also just take over the entire screen.
(copy of my answer on a similar question, Getting the dimensions of the soft keyboard )
I've created a library project get android keyboard height, even when activities don't use the adjustResize
input mode.

- 1,880
- 1
- 18
- 43
As the navigation bars, keyboard, etc are added to the window, you can measure these insets to check if the keyboard is open or not. With Android R, you can measure the keyboard directly, but you can fall back to calculating the keyboard size from the insets for prior versions.
This works on Lollipop and up.
getWindow().getDecorView()
.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
mKeyboardShowing =
insets.getInsets(WindowInsets.Type.ime()).bottom > 0;
if (mKeyboardShowing) {
setKeyboardHeight(
insets.getInsets(WindowInsets.Type.ime()).bottom -
insets.getInsets(WindowInsets.Type.navigationBars()).bottom);
}
} else {
mKeyboardShowing = getNavigationBarHeight() !=
insets.getSystemWindowInsetBottom();
if (mKeyboardShowing) {
setKeyboardHeight(insets.getSystemWindowInsetBottom() -
getNavigationBarHeight());
}
}
return v.onApplyWindowInsets(insets);
}
public int getNavigationBarHeight() {
boolean hasMenuKey = ViewConfiguration.get(MainActivity.this)
.hasPermanentMenuKey();
int resourceId = getResources().getIdentifier("navigation_bar_height",
"dimen",
"android");
if (resourceId > 0 && !hasMenuKey) {
return getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
});

- 404
- 3
- 7
-
`navigation_bar_height ` is not exposed as public method and is not guaranteed to work in all types of devices – AndroidEngineX Jun 09 '22 at 11:23
My solution is the combination of all above solutions. This solution is also hacky but solve the problem (atleast for me).
- I have places on temporary view with transparent background at the bottom of the screen.
- I have added
android:windowSoftInputMode="adjustResize"
flag in activity tag in manifest like @bill suggests. Now main story is in
onGlobalLayout()
. There i calculate the difference between the y axis of temp view and height of root viewfinal View view = findViewById(R.id.base); view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int rootViewHeight = view.getRootView().getHeight(); View tv = findViewById(R.id.temp_view); int location[] = new int[2]; tv.getLocationOnScreen(location); int height = (int) (location[1] + tv.getMeasuredHeight()); deff = rootViewHeight - height; // deff is the height of soft keyboard } });
But anyways to solve the problem of @zeeshan0026 only a single flag in manifest android:windowSoftInputMode="adjustResize"
is enough.

- 414
- 1
- 3
- 15

- 1,516
- 16
- 21
-
4Is it possible to get keyboard height by using `android:windowSoftInputMode="adjustNothing"` ? – VijayRaj Dec 05 '14 at 06:47
-
1If we use adjustNothing flag then the view will not render again when keyboard open so apparently onGlobalLayout should not call and we will not able to get the change in size. Though i did not try by myself but this is what expected. – Gem Dec 17 '14 at 05:56
I have used this to get keyboard height programmatically in android and tested it, please try this once:
myLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
Rect r = new Rect();
parent.getWindowVisibleDisplayFrame(r);
int screenHeight = parent.getRootView().getHeight();
int heightDifference = screenHeight - (r.bottom - r.top);
Log.d("Keyboard Size", "Size: " + heightDifference);
//boolean visible = heightDiff > screenHeight / 3;
}
});
Thank you.

- 554
- 5
- 21
-
1Do not forget removing the `OnGlobalLayoutListener` inside the callback. – Adib Faramarzi Mar 11 '18 at 14:29
-
1I use the same approach, but still some devices seem to have issue. One galaxy s9 with custom keyboard seem to be failing on this. – htafoya Feb 27 '19 at 19:32
-
I finally found the solution to get the height of soft/virtual keyboard. I cannot say this works on all devices, but I tried on some devices both real and emulator devices and it works. I tried on devices from Android API 16 to 29. It is a little bit tricky. Here is my analysis.
First, I tried to subtract between the height of the screen and height of visible frame on top of soft/virtual keyboard by using function of getHeightDifference()
such as below. I found that at the first time the layout is created, right before the keyboard open on EditText's focus, the difference height will depend on Android System Navigation Bar, either the Navigation Bar is shown inside the device screen or not. So, the value of heightDifference
will be 0 if the Nav Bar outside the screen or greater than 0 if it is inside the screen. I'm using a variable of systemNavigationBarHeight
with Integer object (instead of using primitive int
data) to save the first value of that height difference with only one initialization, which I assume that is the height of Nav Bar.
And then in next code block, I check if next height difference is greater than the height of actual Navigation Bar in Android system (or 100 is default just in case if there is no Navigation Bar in Android system), then I subtract again with the value of systemNavigationBarHeight
to get the real height of soft/virtual keyboard.
Hope this will help on someone who look up another answer.
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
private Integer systemNavigationBarHeight = null;
@Override
public void onGlobalLayout() {
int heightDifference = getHeightDifference();
if (heightDifference > 0) {
if (systemNavigationBarHeight == null) {
/* Get layout height when the layout was created at first time */
systemNavigationBarHeight = heightDifference;
}
} else {
systemNavigationBarHeight = 0;
}
if (heightDifference > getDefaultNavigationBarHeight()) {
/* Keyboard opened */
int keyBoardHeight = heightDifference - systemNavigationBarHeight;
} else {
/* Keyboard closed */
}
}
}
}
private int getHeightDifference() {
Point screenSize = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindowManager().getDefaultDisplay().getRealSize(screenSize);
} else {
getWindowManager().getDefaultDisplay().getSize(screenSize);
}
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
return screenSize.y - rect.bottom;
}
private int getDefaultNavigationBarHeight() {
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return getResources().getDimensionPixelSize(resourceId);
}
return 100;
}
}

- 19
- 5
-
I used your code to resolve the issue from react native https://github.com/troZee/react-native-keyboard-dimens. Thank you so much for sharing your idea – Piotr Badura Jun 24 '21 at 11:20
-
Look no more! I've been looking for a solution for this for a long time. After days of trying all the tricks suggested on SOF, I found the perfect solution that actually works.
This GitHub project demonstrates it the best way possible: https://github.com/siebeprojects/samples-keyboardheight
Have fun!

- 790
- 8
- 16
-
2Hi **Look no more!** guy we have tried the same solution and due to this same **Look no more!** we are getting more than 20 bugs through our app. So you definitely need to look more harder instead of no more :D – AndroidEngineX Jun 09 '22 at 11:30
2023 solution
If you use androidx.compose.foundation
you can get ime visibility and height (bottom) as simple as:
val imeVisible = WindowInsets.isImeVisible
val bottom = WindowInsets.ime.getBottom(LocalDensity.current)
To setup, you can follow this video or:
On your acitivty
onCreate
method:window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) WindowCompat.setDecorFitsSystemWindows(window, false)
AndroidManifest.xml
<application ... android:windowSoftInputMode="adjustResize">
Themes.xml
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>

- 450
- 5
- 9
For API >= 30.
@RequiresApi(Build.VERSION_CODES.R)
private fun getKeyboardHeight(view: View): Int {
return view.rootWindowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom -
getNavBarHeight(view)
}
@RequiresApi(Build.VERSION_CODES.R)
private fun getNavBarHeight(view: View): Int {
return view.rootWindowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
}
@RequiresApi(Build.VERSION_CODES.R)
private fun isKeyboardVisible(insets: WindowInsets): Boolean {
return insets.isVisible(WindowInsetsCompat.Type.ime())
}
See also https://www.kodeco.com/18393648-window-insets-and-keyboard-animations-tutorial-for-android-11.

- 26,736
- 15
- 188
- 224
A solution that I've found excellent for me, was to store a global bottom
value, then to add a TreeView Observer and compare the new bottom value with the stored one. Using android:windowSoftInputMode="adjustResize"
private var bottom: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val rect = Rect()
this.window.decorView.getWindowVisibleDisplayFrame(rect)
this.bottom = rect.bottom
this.window.decorView.viewTreeObserver.addOnGlobalLayoutListener {
val newRect = Rect()
this.window.decorView.getWindowVisibleDisplayFrame(newRect)
// the answer
val keyboardHeight = this.bottom - newRect.bottom
// also
if (newRect.bottom < this.bottom) {
//keyboard is open
} else {
//keyboard is hide
}
}
}

- 105
- 1
- 4