Getting the dimensions of the soft keyboard

匆匆过客 提交于 2019-11-26 19:53:50

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.

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

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

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.

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.

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.

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

Ali Zeynali

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.

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

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!

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;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!