Getting the dimensions of the soft keyboard
Asked Answered
A

13

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.

Actinouranium answered 23/11, 2012 at 18:45 Comment(4)
check out this...#2150578Preferable
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 youIchnite
@Actinouranium : Got things you needed ??? ...Ichnite
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.uActinouranium
A
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.

Actinouranium answered 4/1, 2013 at 0:45 Comment(7)
Is the height difference in px or dp?Mastaba
It's in pixels, because height measurements return pixel quantities.Albumose
It won't work if there is more than keyboard shown on the screen, i.e. system buttons (back, home, etc)Scythe
For me (Nexus 7 with Android 5.0) it does take into account system buttons.Fideicommissum
Which display components cover in react-top or rect-bottom?Provincetown
This works on most devices, but not a few. Modern Samsung phones have a soft keyboard with a variable height and an extra menu (for emogis, gifs, settings etc.) that appears to not register as part of this keyboard layout.Ascribe
Not working. For me it's some negative valueBenefield
G
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

Greek answered 1/2, 2014 at 12:24 Comment(3)
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.Greek
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?Washko
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 6Greek
Y
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;
                }
            });
Yale answered 10/4, 2013 at 3:43 Comment(2)
thank you, status_bar_height is very very important if you want to translate editview by YWicker
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.Ascribe
G
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.

Gaither answered 22/9, 2016 at 7:10 Comment(0)
C
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.

Cilium answered 10/6, 2015 at 19:37 Comment(1)
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 dynamicPerrins
D
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

Dulcimer answered 14/7, 2021 at 15:22 Comment(0)
B
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.

Binetta answered 12/1, 2017 at 0:25 Comment(0)
C
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 :)

Commodus answered 5/7, 2013 at 6:14 Comment(1)
and sorry for not adding it as a comment, because I simply couldn't.Commodus
V
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.

Varga answered 21/7, 2017 at 7:11 Comment(0)
N
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 ;)

Neighbor answered 4/6, 2016 at 11:21 Comment(0)
R
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!

Retroflexion answered 21/12, 2016 at 20:3 Comment(0)
A
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;
Alban answered 24/6, 2018 at 4:59 Comment(0)
M
0

I am using Cocos creator game engine in which the below modification worked fine. In the java code of cocos creator's android build or inside the vent listener added below code and somehow managed to get the key board size

    View rootView = getWindow().getDecorView().getRootView();
    rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            rootView.getWindowVisibleDisplayFrame(r);
            int screenHeight = rootView.getHeight();
            int keypadHeight = screenHeight - r.bottom;

                System.out.println(keypadHeight + " is keypadHeight ");
                CocosHelper.runOnGameThread(new Runnable() {
                    @Override
                    public void run() {
                   
                   CocosJavascriptJavaBridge.evalString("window[\"className\"].functionName(\""+keypadHeight+"\")");
                    }
                });
        }
    });
Michellmichella answered 12/4 at 11:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.