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: 184
Last edited:

johnaaronrose

Active Member
Licensed User
Longtime User
You can combine both flags if you like with Bit.Or(value1, value2).
I've decided not to use the JavaObject method to disable the default behaviour of Landscape orientation. Instead I'm using the GetDevicePhysicalSize sub (outlined in the Beginner's Guide) to decide whether the device is a phone or a tablet. Then I use the Phone.SetScreenOrientation method (from the Beginner's Guide) to set Portrait/Landscape corresponding to Phone/Tablet. Also, I've changed the design layout of the Landscape variant to have the views much higher on the screen & therefore see all the views at runtime when the keyboard is displayed. One point I noticed is that a Return symbol key is shown in the keyboard rather than Next/Done. How can this be rectified (i.e. display Next/Done as appropriate)?
PS The Next/Done usage was set using the Reflector Library with the command "Refl.RunMethod2("setImeOptions",IME,"java.lang.int")" where IME = 5 or 6 corresponding to Next or Done.
 
Last edited:

johnaaronrose

Active Member
Licensed User
Longtime User
Next / Done button should appear when the EditText is in single line mode.
SingleLine is set to True on all my EditText views: it's the default in the Designer and I have not changed it in either the Designer or code.
 

TheWind777

Active Member
Licensed User
Longtime User
I have a strange need.

I am using (trying to use) the software keyboard's ability to copy a word to the clipboard by double-clicking on the word in an EditText box, then clicking 'copy' at the top of the panel.

Next, I am using the cursor position to find and grab the sentence which contains that word (by searching backwards for punctuation or the beginning of the text, then forward till punctuation; the get rid of leading spaces.

The sentence-grabbing routine works (albeit slowly)... but here's the problem:

I'm trying to not bring up the keyboard at all. I only want them to be able to double-click on a word - which would then show the two edit gadgets at the left and right of the word... then have them click 'copy'. If I could just have them have that capability - that would do it.

As it is now... if the text is going to be behind the keyboard (once it pops-up), they have to quickly and expertly double click that word. Then the keyboard pops up and they can only tell whether they actually highlight the word by seeing the two blue edit things on either-side of the word (and it will show similar words at the top of the keyboard.

So, know any way to have them retain the selection and copying of words without bringing up the keyboard for that EditText box?
 

TheWind777

Active Member
Licensed User
Longtime User
Note that it is better to start a new thread for this question.

Have you tried to set the InputType to INPUT_TYPE_NONE?
Hmmm... So that would be:

EditText.InputType = EditText.INPUT_TYPE_NONE

Where EditText is the name of my EditText Box?
 

TheWind777

Active Member
Licensed User
Longtime User
Note that it is better to start a new thread for this question.

Have you tried to set the InputType to INPUT_TYPE_NONE?
No, that just turns off any capability to copy-and-paste at all. You can't highlight, you can't do anything.

Is there any way to turn the keyboard invisible? I'm sure there must be an invisible flag for the keyboard if one could get at the structure.

Then, possibly, you could do all the editing like copy/paste highlighting and moving around of those editing gadgets without actually changing the text at all (which is what I need). I just need the user to double-click to highlight a word - then a copy to the clipboard. If they couldn't actually edit any text, and definitely not change any of the text, that would be great.
 

TheWind777

Active Member
Licensed User
Longtime User
I think the sequence of events should be added to the description.
It is MyView_FocusChanged, IME_HeightChanged.

(because it gave me problems)

Do you have the code that you can post? Or, possibly... your project, archived. I'd love to see how you can move the bottom of an EditText box to be on the top of the keyboard so the keyboard isn't in front of the text.
 

luciano deri

Active Member
Licensed User
Longtime User
Hi. I need accept in a edit text only number by virtual keyboard, but if i have an imput of barcode scanner (keyboard emulation) i must check the special char prefix not numeric. With standar keyboard, the edit text numerico don't accept char. Can do this with IME library? Tanks.
 

badal405

Member
Licensed User
Longtime User
B4X:
Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int)
  btnHideKeyboard.Top = NewHeight - btnHideKeyboard.Height
  EditText1.Height = btnHideKeyboard.Top - EditText1.Top
End Sub

Erel how can i change the CustomListView height since it doesn't have "Height" property.
 

koaunglay

Member
Licensed User
Longtime User
The state of the keyboard when the activity appears is set in the manifest file.
You should use this code (manifest editor):
B4X:
SetActivityAttribute(main, android:windowSoftInputMode, stateAlwaysVisible)
Thanks Erel ! Can I use this keyboard when I use device sms apk?
The state of the keyboard when the activity appears is set in the manifest file.
You should use this code (manifest editor):
B4X:
SetActivityAttribute(main, android:windowSoftInputMode, stateAlwaysVisible)
 

anebojsa

New Member
Licensed User
Longtime User
I moved EditText1 in the designer in Erel's sample. How to solve the problem that the field is visible when entering text in this field.
 

Attachments

  • IME_anebojsa.ZIP
    349.9 KB · Views: 486
Status
Not open for further replies.
Top