34

Is there a way to know the size of the keyboard that is shown in the screen?

I am using Cocos2dx for programming, but I want to know the height of the keyboard shown in screen in the part of Android or the part of Cocos, it does not matter.

I know that Keyboard has a getHeight() method but I don't want to create new keyboards, i want to use the default one.

Yossi Dahan
  • 5,389
  • 2
  • 28
  • 50
Rudy_TM
  • 1,420
  • 4
  • 15
  • 27
  • check out this...http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android – Praful Bhatnagar Nov 23 '12 at 18:50
  • Do you want keyboard then cocos2d-x has already incorporated the android keyBoard you may check in the Test Classes -> TextInput where they are using android keyboard in cocos2d-x ... check if it may help you – user1169079 Nov 29 '12 at 07:01
  • @Rudy_TM : Got things you needed ??? ... – user1169079 Dec 17 '12 at 17:00
  • No :/ we can not get the height of the keyboard, the problem is that we want to push up textfield if they are behind the keyboard. we put a constant 'activity.getCurrentFocus().getMeasuredHeight()' when the keyboard is called and multiply it with the number of rows of the keyboard keys, in the smartphones it works, but in the tablets, it does not work, so that is not the solution :/ but meanwhile we will be using this u.u – Rudy_TM Dec 17 '12 at 19:07

12 Answers12

40

We did it with this

myLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {

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

                }
            });

We only resize views with the keyboard, so we could use this.

Rudy_TM
  • 1,420
  • 4
  • 15
  • 27
23
Rect r = new Rect();
View rootview = this.getWindow().getDecorView(); // this = activity
rootview.getWindowVisibleDisplayFrame(r);

Result of this is the amount of space your application uses on screen (works even when activity is not resized). Obviously remaining screen space will be used by the keyboard ( if its visible)

Found id up here: https://github.com/freshplanet/ANE-KeyboardSize/blob/master/android/src/com/freshplanet/ane/KeyboardSize/getKeyboardY.java

FDIM
  • 1,981
  • 19
  • 21
  • Are you sure that keyboard is visible at that point in time? I experienced some issues with that and I had to get dimensions when activity layout was updated. – FDIM Jun 17 '14 at 21:38
  • Thanks for this simplest and useful answer! Will this work with phones which use on-screen system buttons such as LGs? And you don't have any issues with this solution so far? – Jenix Oct 05 '16 at 19:42
  • Yep, I used nexus 4 when I was developing a game, thus I had to deal with on-screen buttons. Project is on-hold, but I still installed it on Z5 to give it a go - still worked fine on Android 6 – FDIM Oct 08 '16 at 14:49
9

if your activity is not fullscreen, using code below:

content.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {
                    // TODO Auto-generated method stub
                    if (keyBoardHeight <= 100) {
                        Rect r = new Rect();
                        content.getWindowVisibleDisplayFrame(r);

                        int screenHeight = content.getRootView()
                                .getHeight();
                        int heightDifference = screenHeight
                                - (r.bottom - r.top);
                        int resourceId = getResources()
                                .getIdentifier("status_bar_height",
                                        "dimen", "android");
                        if (resourceId > 0) {
                            heightDifference -= getResources()
                                    .getDimensionPixelSize(resourceId);
                        }
                        if (heightDifference > 100) {
                            keyBoardHeight = heightDifference;
                        }

                        Log.d("Keyboard Size", "Size: " + heightDifference);
                    }
                    // boolean visible = heightDiff > screenHeight / 3;
                }
            });
Habbot Phan
  • 91
  • 1
  • 2
  • thank you, status_bar_height is very very important if you want to translate editview by Y – djdance Jun 15 '14 at 20:33
  • 1
    This gets the height of the resource, which may be different from what is actually drawn. For example, I on a tablet with physical buttons that are not on the screen at all the resource still exists and thus returns 48dp. – SMBiggs Jan 30 '23 at 15:20
5

If you want to calculate the Virtual Keyboard height while your activity does not change in size (adjustPan) then you can use this sample:

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

It uses a hidden window in order to calculate the height difference between the window and the root view of the activity.

Siebe Brouwer
  • 671
  • 6
  • 3
4

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.

ctate
  • 1,379
  • 10
  • 11
  • 2
    do you have find a solution or is android just not capable to provide real apps? i mean, being super dynamic in one sense but not providing to handle the dynamic – Henning Luther Feb 16 '17 at 21:59
4

After 2020, if your min SDK large or equal then 21, you can check the visibility and height of IME by below functions:

fun isKeyboardVisible(attachedView: View): Boolean {
    val insets = ViewCompat.getRootWindowInsets(attachedView)
    return insets?.isVisible(WindowInsetsCompat.Type.ime()) ?: false
}

fun getKeyboardHeight(attachedView: View): Int {
    val insets = ViewCompat.getRootWindowInsets(attachedView)
    return insets?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
}

Ref: Animating your keyboard (part 1). New WindowInsets APIs for checking the… | by Chris Banes | Android Developers | Medium

Samuel
  • 201
  • 2
  • 5
3

I know this is an old post, but I noticed that the chosen solution for me did not work on all devices. There seemed to be a discrepancy and so I implemented this and it seems to be a catch all:

        final int[] discrepancy = new int[1];
        discrepancy[0] = 0;

        // this gets the height of the keyboard
        content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                View rootview = activity.getWindow().getDecorView(); // this = activity
                rootview.getWindowVisibleDisplayFrame(r);

                int screen_height = rootview.getRootView().getHeight();
                int keyboard_height = screen_height - (r.bottom + r.top) - discrepancy[0];

                if (discrepancy[0] == 0) {
                    discrepancy[0] = keyboard_height;
                    if (keyboard_height == 0) discrepancy[0] = 1;
                }

                int margin_bottom = keyboard_height + Helper.getDp(10, activity);

                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) carousel_container.getLayoutParams();
                params.setMargins(0, 0, 0, margin_bottom);

                //boolean visible = heightDiff > screenHeight / 3;
            }
        });

When the listener is first called it measures the screen without a keyboard and if there is a discrepancy I account for it the next time around. If there is no discrepancy I set the discrepancy to 1 just so it is no longer 0.

noshaf
  • 75
  • 6
2

in cocos2d-x we have got CCEditBox.

Inside Extensions->GUI->CCEditBox, you can find the class CCEditBox.

The beauty is that it hides the keyboard of tapping somewhere else on the scene. and automatically moves the keyboard up incase your edit box was placed too low on the scene.

If you are using cocos2d-x v2.1.3 then you can navigate to sample Project by going to

samples->cpp->TestCpp->Classes->ExtensionTest->EditBoxTest.

I'm just going to use it instead of CCTextField from now on. just came across it yesterday :)

Azhar Yousuf
  • 111
  • 6
1

After hours of searching I found a solution if you want to set windowSoftInput="adjustPan"

Here is the code snippet:

    final View root  = findViewById(android.R.id.content);
    root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    Rect r = new Rect();
    {
        root.getWindowVisibleDisplayFrame(r);
    }
    @Override
    public void onGlobalLayout() {
        Rect r2 = new Rect();
        root.getWindowVisibleDisplayFrame(r2);
        int keyboardHeight = r.height() - r2.height();
        if (keyboardHeight > 100) {
            root.scrollTo(0, keyboardHeight);
        }
        else {
            root.scrollTo(0, 0);
        }
    }
});

In this code, after I found the keyboard height I scroll the view up to not covered by the keyboard which is the main reason for finding the keyboard height.

According to the docs :

void getWindowVisibleDisplayFrame(Rect outRect) : Retrieve the overall visible display size in which the window this view is attached to has been positioned in.

Faysal Ahmed
  • 7,501
  • 5
  • 28
  • 50
alizeyn
  • 2,300
  • 1
  • 20
  • 30
0

The ROOT_VIEW of an android display screen can be visualized as being a single screen view with VISIBLE DISPLAY FRAME which displays your activity's view.

This VISIBLE DISPLAY FRAME is adjusted when SOFT KEYBOARD is displayed or hidden from the screen.

NOTE : Please look at the two images by clicking on the links given below for better understanding

So the ROOT VIEW of a display screen can be visualized as : RootView of display screen

The adjustment of VISIBLE DISPLAY FRAME with the opening and closing of SOFT KEYBOARD can be visualized as : VISIBLE_DISPLAY_SCREEN adjustment

This adjustment of the VISUAL DISPLAY FRAME can be very well used to find out the height of the keyboard as :

(when the soft keyboard is open)

SOFT_KEYBOARD_HEIGHT = ROOT_VIEW_HEIGHT - (VISUAL_DISPLAY_FRAME_HEIGHT + EXTRA_SCREEN_HEIGHT)

The code to achieve the above is :

int mExtraScreenHeight=-1, mKeyboardHeight=-1;
boolean mKeyboardOpen;



    rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {

            int rootViewHeight, visibleDisplayFrameHeight, fakeHeight;

            /* (rootViewHeight - visibleDisplayFrameHeight) is not the real height of the keyboard
                it is the fake height as it also consist of extra screen height
                so FAKE_HEIGHT = KEYBOARD_HEIGHT + EXTRA_SCREEN_HEIGHT

                To get keyboard height extra screen height must be removed from fake height
             */

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

            rootViewHeight = rootView.getRootView().getHeight();
            visibleDisplayFrameHeight = rect.height();

            fakeHeight = rootViewHeight-visibleDisplayFrameHeight;

            if (mExtraScreenHeight == -1){
                mExtraScreenHeight=fakeHeight;
            }
            /* Suppose the soft keyboard is open then the VISIBLE_DISPLAY_FRAME is in reduced size
                due to the space taken up by extra screen and the keyboard but when the soft keyboard closes
                then KEYBOARD_HEIGHT=0 and thus FAKE_HEIGHT = EXTRA_SCREEN_HEIGHT
             */
            else if (fakeHeight <= mExtraScreenHeight){
                mExtraScreenHeight=fakeHeight;
                mKeypadOpen=false;
            }
            else if (fakeHeight > mExtraScreenHeight){
                mKeypadHeight=fakeHeight-mExtraScreenHeight;
                mKeypadOpen=true;
            }
        }
    });

NOTE : The onGlobalLayout() function will be called only when the global layout changes like when the soft keyboard opens. So the soft keyboard must be open at least once to get the soft keyboard height.

It worked for me ;)

0

Sorry for not being able to comment, two or three of the answers helped me solve my issue and they were related to using the AddOnGlobalLayoutListener and then determining the remaining height before and after a keyboard showed up.

The solution I used was based off of Rudy_TM's answer.

HOWEVER, one thing that I had to find was that in order for that method to work, you must have the following line somewhere

Window.SetSoftInputMode(SoftInput.AdjustResize);

Before I had SoftInput.AdjustNothing (or something like that) and it would not work. Now it works perfect. Thanks for the answers!

0

Complete answer & worked perfectly for me:

  Rect r = new Rect();
  View rootview = this.getWindow().getDecorView(); // this = activity
  rootview.getWindowVisibleDisplayFrame(r);
  int keyboardHeight = rootview.getHeight() - r.bottom;
Amit
  • 1,841
  • 1
  • 19
  • 36