Detect keyboard height

Hello

I’m trying to write a plugin to detect the keyboard height on Android and iOS.

I’ve started with Android [as usual, bad call…] and of course hit a wall.

The usual method of detecting the keyboard height doesn’t seem to work with opengl view, or I am doing something stupid so it does not.

Anyway…  the usual way to do it is described here: http://stackoverflow.com/a/4737265/487605

But my rect has values of 10000 or -10000… strange.

I think I will let this rest for a moment, and I’ll write the iOS plugin instead, as it will probably just work out of the box [wishful thinking]. I’m just wondering how do you make sure that your text fields/buttons are not hidden by the keyboard on Android? Have you got better ideas?

Thanks

Krystian

The reason you cannot get the keyboard height in the SDK product now is the Engineers  have said it’s not possible.  Perhaps its OpenGL causing the problem.

Rob

I assign native textfields/boxes to a new group and simply use transition.to modifying the y coordinate up and down to move above the keyboard.

nativeGroup = display.newGroup()

save the y coord of the group after creating the objects

nativeGroupY = nativeGroup.y

create two functions called by text field listeners…

local function moveFieldsDown()

    transition.to( nativeGroup, { time=g.fieldTrans, y=(navGroupY)} )

end

local function moveFieldsUp()

    transition.to( nativeGroup, { time=g.fieldTrans, y=(navGroupY - g.fieldOffset)} )

end

ex object listener

local function moveDescription(event) 

–    print(event.phase)

    if event.phase == “began” then

        moveFieldsUp()

    elseif event.phase == “ended” then

        moveFieldsDown()

        native.setKeyboardFocus(nil)

    end

end

guy.stockwell, thanks a lot, this is what  I’m trying to achieve, however I need to get a proper value for the g.fieldOffset :slight_smile:

How do you get a proper value?

Right now I simply transition the whole scene to make the edited input box in the 0.25 of the screen height, but that’s not a good solution :confused: it just looks… yuck.

Rob: I’m looking for etnerprise solution, not the SDK solution. I think I have an idea on how to do that - since I cannot do it with opengl view,  I might be able to substitude it for a moment with something else to determine the height of the keyboard. Since user is editing something, there’s nothing else CPU intensive going on. It should work.

You can’t fetch the keyboard height on Android.  It just isn’t possible.  If you look at the response to the stackoverflow solution that you linked to, you’ll see a similar response.  The problem with that stackoverflow solution is that he is setting up the app to be “resized” when the keyboard is displayed.  Meaning that the keyboard is no longer overlaid on top.  By doing that, he is able to guess at the height of the keyboard based on the height of his app and the height of the screen.  The problem with this solution, as noted by the stackoverflow response, is that this height information is useless now because the keyboard is no longer overlaid on top of the app.

The *only* real solution on Android is to do one of the following:

  1. Set up the Android activity input focus field to be slid into focus via the “adjustPan” AndroidManifest.xml setting.  This can also be done dynamically via the Java setSoftInputMode() API.

  2. Set up the Android activity to be resized between the top status bar and bottom keyboard, preventing the keyboard from being overlaid on top.  This is what that stackoverflow solution does and it does this via the “adjustResize” setting.  Problem with this is if your Corona app’s config.lua is set up to use content scaling (ie: letterbox, zoomEven, zoomStretch) then the app will be rescaled to something even smaller when your activity is squished by the keyboard.  Most Corona developers will not like this solution.

In my opinion, #1 is the best solution and is pretty easy to implement on Android.  The only issue here is implementing something similar on iOS is actually difficult.  On iOS, fetching the keyboard height is the simplest solution.  Nothing is ever easy when doing cross-platform development, eh?

This is what I use that works well for most devices.

g.fieldOffset = 165

if string.sub(system.getInfo(“model”),1,4) == “iPad” then

    g.fieldOffset = 80

end

g.fieldTrans = 200

Apple is allowing third-party keyboards for the first time in iOS 8 and Swype, SwiftKey, Fleksy and TouchPal will be releasing the first ‘iconless’ apps for the iPhone and iPad today. I wonder if all these 3rd party keyboards will match the native keyboard in height and width. If not we will have a new challenge on our hands… 

Do the keyboards just get to customize the default keyboards appearance? Or can they be completely customized like on android?

The reason you cannot get the keyboard height in the SDK product now is the Engineers  have said it’s not possible.  Perhaps its OpenGL causing the problem.

Rob

I assign native textfields/boxes to a new group and simply use transition.to modifying the y coordinate up and down to move above the keyboard.

nativeGroup = display.newGroup()

save the y coord of the group after creating the objects

nativeGroupY = nativeGroup.y

create two functions called by text field listeners…

local function moveFieldsDown()

    transition.to( nativeGroup, { time=g.fieldTrans, y=(navGroupY)} )

end

local function moveFieldsUp()

    transition.to( nativeGroup, { time=g.fieldTrans, y=(navGroupY - g.fieldOffset)} )

end

ex object listener

local function moveDescription(event) 

–    print(event.phase)

    if event.phase == “began” then

        moveFieldsUp()

    elseif event.phase == “ended” then

        moveFieldsDown()

        native.setKeyboardFocus(nil)

    end

end

guy.stockwell, thanks a lot, this is what  I’m trying to achieve, however I need to get a proper value for the g.fieldOffset :slight_smile:

How do you get a proper value?

Right now I simply transition the whole scene to make the edited input box in the 0.25 of the screen height, but that’s not a good solution :confused: it just looks… yuck.

Rob: I’m looking for etnerprise solution, not the SDK solution. I think I have an idea on how to do that - since I cannot do it with opengl view,  I might be able to substitude it for a moment with something else to determine the height of the keyboard. Since user is editing something, there’s nothing else CPU intensive going on. It should work.

You can’t fetch the keyboard height on Android.  It just isn’t possible.  If you look at the response to the stackoverflow solution that you linked to, you’ll see a similar response.  The problem with that stackoverflow solution is that he is setting up the app to be “resized” when the keyboard is displayed.  Meaning that the keyboard is no longer overlaid on top.  By doing that, he is able to guess at the height of the keyboard based on the height of his app and the height of the screen.  The problem with this solution, as noted by the stackoverflow response, is that this height information is useless now because the keyboard is no longer overlaid on top of the app.

The *only* real solution on Android is to do one of the following:

  1. Set up the Android activity input focus field to be slid into focus via the “adjustPan” AndroidManifest.xml setting.  This can also be done dynamically via the Java setSoftInputMode() API.

  2. Set up the Android activity to be resized between the top status bar and bottom keyboard, preventing the keyboard from being overlaid on top.  This is what that stackoverflow solution does and it does this via the “adjustResize” setting.  Problem with this is if your Corona app’s config.lua is set up to use content scaling (ie: letterbox, zoomEven, zoomStretch) then the app will be rescaled to something even smaller when your activity is squished by the keyboard.  Most Corona developers will not like this solution.

In my opinion, #1 is the best solution and is pretty easy to implement on Android.  The only issue here is implementing something similar on iOS is actually difficult.  On iOS, fetching the keyboard height is the simplest solution.  Nothing is ever easy when doing cross-platform development, eh?

This is what I use that works well for most devices.

g.fieldOffset = 165

if string.sub(system.getInfo(“model”),1,4) == “iPad” then

    g.fieldOffset = 80

end

g.fieldTrans = 200

So as Josh noted, there is some awkwardness in obtaining the keyboard height. It’s not the same as getting the screen width/height because there is no API on Android as far as we can tell, and on iOS, that value is indirectly available when the OS notifies the app that the keyboard is about to be shown, i.e. the user has to take an action that shows the keyboard in order for Corona to be able to pass those values to you, so it’s not that helpful.

It seems what people really want is the following: when a native textfield/textbox is selected and causes a keyboard to appear, the window will shift upward (all Corona content shifts upward) so that the textfield you just selected won’t be obscured by the keyboard.

That’s basically Josh’s option #1 from above, so that’s what we’ll be looking into.

Walter, 

Thanks for thinking this through. I think moving Corona content blindly upwards as much as the keyboard height will not work as the entry field might be at the top of the screen and get obscured if you do this. We would need to move the screen upwards only when the entry field is on the lower part of the screen and is about to be obscured by the keyboard. This is why normally we would want to know the keyboard height and move the screen as needed and then back downwards once entry is completed. if Corona SDK is going to do it for us then it needs to be a little more clever than moving the whole screen up at all times. 

Lets think this through and find a solution that will work. Thanks much!!! 

Regards,

Kerem

Indeed, that is our intention.

Super!!! This is great news. Thanks much. 

If corona could offer the height rather than animating everything when the keyboard is about to show, since that is really the only time we need to know of the value, that would be perfect as it would make things infinitely easier and give us control of what to do. We for example only want to animate one group when the keyboard is about to show, being able to access the keyboard height value would eliminate all issues associated with that value.

Thanks tons for adding this!!

Ah just saw the fix added in the latest daily. While it technically works now it still doesn’t work very well with textfields that don’t have a background set and that we provided a custom background for which exceeds the top/bottom boundaries of the text.

I still think the best solution would just be to give us access to the actual keyboard height and then we can do whatever we choose with it as the possibilities are all there, the only thing we are lacking is knowing the exact value. I’m not to keen on these forced animations and forced behaviours that we have no control over as it forces us to ‘esthetically’ animate our app in certain ways even if it doesn’t suit the behaviour of our app at all, and it feels like it doesn’t benefit the Corona SDK either to force certain animatinos on users, it only takes more work for the engineers to implement and even then some users might not want it. Why not just give the devs the tools and then they can create the animations themselves using simple transitions and whatnot :slight_smile:

While the fix currently works for us, it still doesn’t work that well because sure, the user now might see what he/she is typing, but they still wont see the full background we deisgned for the textfield and things still look buggy, and I just hope this isn’t the final version of this feature that we’ll get as we’re otherwise stuck with a bug that is considered “fixed” in Coronas eyes and getting a fix for this implement will take us forever from here on.

Sorry for the long post, but I just want to see this get done right as we’ve waited for it for so long and now that it’s finally here it’s going to work half-ok for no good reason. I think the best way to go about doing it is to just let us access the keyboard height and we’ll be able to animate things in any way, shape or form we need :slight_smile:

And what about Android? How to cater for the same need on Android devices?