Android Tutorial Handle the soft keyboard with the IME library

Status
Not open for further replies.
Android has very good support for custom input method editors (IMEs).
The downside for this powerful feature is that interacting with the soft keyboard can be sometimes quite complicated.

This library includes several utilities that will help you better handle the soft keyboard.

The attached example demonstrates the available methods.

1724752241705.png


Note that the IME object should be initialized before it can be used.

Handling the screen size changed event
When the keyboard opens the available screen size becomes much shorter. By default if the EditText is located near the bottom of the screen, Android will "push" the whole activity and make the EditText visible. This mode is named "adjustPan" mode.

By calling IME.AddHeightChangedEvent you are changing the activity to "adjustSize" mode. In this mode the activity will not be pushed automatically. Instead the HeightChanged event will be raised when the keyboard is shown or hidden.

Update: You should explicitly set the adjustSize mode with the manifest editor. This is done by adding the following manifest editor code (for each activity):
B4X:
SetActivityAttribute(main, android:windowSoftInputMode, adjustResize|stateHidden)

For example the following code makes sure that the button at the bottom is always visible and sets the large EditText height to match the available height:
B4X:
Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int)
   btnHideKeyboard.Top = NewHeight - btnHideKeyboard.Height
   EditText1.Height = btnHideKeyboard.Top - EditText1.Top
End Sub

The result is:

1724752272411.png


Note that this method will not work if the activity is in full screen mode (Issue 5497 - android - adjustResize windowSoftInputMode breaks when activity is fullscreen - Android).

Showing and hiding the keyboard
IME.ShowKeyboard - Sets the focus to the given view and opens the soft keyboard.
IME.HideKeyboard - Hides the keyboard (this method is the same as Phone.HideKeyboard).

Handle the action button
By calling IME.AddHandleActionEvent you can override the default behavior of the action button (the button that shows Next or Done).
This event is similar to EditText_EnterPressed event. However it is more powerful. It also allows you to handle the Next button and also to consume the message (and keep the keyboard open and the focus on the current EditText).

This can be useful in several cases.
For example in a chat application you can send the message when the user presses on the done button and keep the keyboard open by consuming the message.

You can also use it to validate the input before jumping to the next view by pressing on the Next button (note that the user will still be able to manually move to the next field).

You can use the Sender keyword to get the EditText that raised the event.
For example:
B4X:
Sub IME_HandleAction As Boolean
   Dim e As EditText
   e = Sender
   If e.Text.StartsWith("a") = False Then
      ToastMessageShow("Text must start with 'a'.", True)
      'Consume the event.
      'The keyboard will not be closed
      Return True
   Else
      Return False 'will close the keyboard
   End If
End Sub

Custom filters
EditText.InputType allows you to set the keyboard mode and the allowed input.
However there are situations where you need to use a custom filter. For example if you want to accept IP addresses (ex: 192.168.0.1). In this case none of the built-in types will work. Setting the input type to INPUT_TYPE_DECIMAL_NUMBERS will get you close but it will not allow the user to write more than a single dot.
IME.SetCustomFilter allows you to both set the keyboard mode and also to set the accepted characters.
In this case we will need a code such as:
B4X:
IME.SetCustomFilter(EditText3, EditText3.INPUT_TYPE_NUMBERS, "0123456789.")
Note that this is only a simple filter. It will accept the following input (which is not a valid IP address):
....9999.

Updates:

The example was updated and is now based on B4XPages. Note that additional code in the Main module (https://www.b4x.com/android/forum/t...or-managing-multiple-pages.118901/post-745090) and don't miss the manifest editor code.
 

Attachments

  • IME_Example.zip
    14.8 KB · Views: 80
Last edited:

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Might be able to tweak windowSoftInputMode in your Manifest file to always show it. Usually something needs focus (possibly a hidden off screen Edit Text or something) otherwise you have to grab key presses at the activity level and deal with other controls getting focus, etc.

I realize phones/devices with hardware keyboards have this type of capability along with other interesting things like arrow buttons (Swift Key has this too which is nice), and Android has some cool functionality to pick the view that gets focused with arrow keys and lots of other things. If you don't have a hardware keyboard though it will be confusing for the user and take up a lot of screen. If all you need are a few buttons then Erel's suggestion is best. There is an example right in the tutorial documents too.
 

TomA

Active Member
Licensed User
Longtime User
Edittext in landscape mode on smaller screens

Just now getting around to putting this into my project. Thanks!!!

It is working great for IP addresses and the numeric keyboard except for one issue. When I rotate to landscape and there is simply not enough room to show the normal EditText (pushing it would do no good), Android shows a different input box (not the normal EditText). This different box does not show the existing periods. In the attached screenshot, there should be periods in it (as it is an IP address) but they are not there. Oddly enough, I can enter more periods (though it doesn't show them) and if I hide the keyboard or rotate back to portrait then the extra periods I added appear.

To be fair though, after seeing this happen in my app I tried it in a competing app and it has the same problem. For that reason I can accept it if this is the way it must be (could be an Android problem or Swype problem). But I am curious if there is any way to work around it?

Erel thought this was an Android bug, but it is not. It seems to happen on smaller screens - for example it does not happen on my 10" tablet but does happen on my Google Nexus phone. I encountered this problem in an app I am building and raised the issue with the Android folks (code.google.com).
The reply I got was: 'It is not a bug, it's something called "extract mode". The text field is not resized, a new window appears on top of your application. It's done this way because there is not enough room to display both the keyboard and the app properly in landscape.'

The point is that, for some apps (only the developer knows for sure), there is enough room for useable data in landscape mode even with the keyboard displayed - the one example I showed was from the Colossal Cave text adventure where it would have displayed useable text.

You can read the details of my post and the response on that site - Issue 40877 - android - Textedit field is wrong size in landscape mode - Android - An Open Handset Alliance Project - Google Project Hosting
Might help to get this fixed (to not make it a default behavior) if enough people added their comments to this issue.
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
It is easy to set the Ime options and turn off the screen extract mode. I do it in my view manager class if you need code. I also took a different approach in my Line Layout library and it uses a couple different modes depending on if you set MaxLines to 0 or 1. You can turn it off and also force it. It is a different textview that shows, so any formatting wont show. You also don't get Ime height change events even with it off, so it always pans the screen.
 

TomA

Active Member
Licensed User
Longtime User
You also don't get Ime height change events even with it off, so it always pans the screen.
I am not sure what you mean here. I used the IME option to turn off extract mode and it gets the height change event with no problem.
 

airblaster

Active Member
Licensed User
Longtime User
I'm trying to show the soft-keyboard automatically with
B4X:
Dim IME As IME
   IME.ShowKeyboard(et)
However, the keyboard doesn't show.
I tested this on a LG P990 with Android 4.0.3.
Is this a bug?
 

airblaster

Active Member
Licensed User
Longtime User
The code is placed in Activity_Resume, the corresponding EditText is declared in Activity_Create.
 

Cothek

Member
Licensed User
Longtime User
I cant get" IME1.AddHeightChangedEvent" to work.

In my program I have the following:

Sub globals
Dim IME1 As IME



Sub Activity_Create(FirstTime As Boolean)
IME1.Initialize("IME1")
IME1.AddHeightChangedEvent


Sub IME1_HeightChanged(NewHeight As Int, OldHeight As Int)
edtMain.Height = NewHeight - (edtMain.Top+10%y)
End Sub

It work 3 out of 5 time, but the 2 ot of 5 time, it does not do the command in Sub IME1_Hei....

Is something missing?

Kind regards
Jakob

I am having similar issues with the keyboard. I've noticed that when I first run my app and click on an edit text the HeightChanged event is triggered but if I change screens it no longer triggers the event. Any ideas on the cause?
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hallo,

when i type the string in the edittext1, then freeze the button1, until hide Keyboard.
 

sherifyeheia

New Member
Licensed User
Longtime User
layout changes after pressing phone back button

after pressing the phone back button to hide the keyboard the edittext and button places are not the same as the first layout .
 

sherifyeheia

New Member
Licensed User
Longtime User
Sub keyboard_HeightChanged(NewHeight As Int, OldHeight As Int)
signtext_done.Top = NewHeight - signtext_done.Height
sign_text.Height = signtext_done.Top - sign_text.Top
End Sub
 
Status
Not open for further replies.
Top