In this article I revisit (again) the seemingly perennial problem of controls being obscured by the virtual keyboard when it appears.
The code related to this article was tested with Delphi Tokyo 10.2.3, however it may work with earlier versions.
TL;DR: The demo code is part of, and relies on units from the KastriFree project.
Wind back the clock five years, and you’ll find yourself at the first article I wrote regarding this issue. The first revision of the article was two and a half years ago, however this time the solution is substantially different.
A “replacement” TVertScrollBox
In this solution, I’ve created a descendant of TVertScrollBox, that is used as an “interposer” class. This means that if the unit is added to the uses clause after the appearance of FMX.Layouts, the form or frame will create an instance of the interposer, and so will have all the required behaviour.
In order for everything to work, the controls within the TVertScrollBox need to be contained within a control (e.g. a TLayout) that has its Align property set to Top:
This control is assigned to the ControlsLayout* property of the interposer TVertScrollBox, and when the Virtual Keyboard appears, the control is resized, and the viewport position of the TVertScrollBox is changed, if required.
(*It may well have been named something like ControlsContainer, because it does not need to be a layout; just a TControl descendant)
Taking care of TMemo
The viewport positioning is based on the position of the control, and its height, depending on the type of control. If it is a TCustomMemo descendant, the positioning is determined by the position of the caret. If the return key is pressed, the caret position will move further down, and the positioning is recalculated:
If you examine the code, you may note that the TIdleMessage is used to check when focus changes and caret position changes occur. This is because the Virtual Keyboard may remain visible (and therefore possibly no Virtual Keyboard “hide” or “show” message) when focus changes or caret position changes and position needs to be recalculated.
Orientation Changes
This solution also allows for when the orientation of the device is changed. On iOS, a change in orientation causes the Virtual Keyboard to disappear, however on Android, the Virtual Keyboard remains visible, so the new size of the Virtual Keyboard is obtained, and the positioning is recalculated.
Please consider this solution to be a work in progress, as I have not checked every single scenario, however it has become by far the easiest since its beginning as there is far less work for the developer to do.
G’day, Dave. I don’t know if this is the place to ask, but I have been struggling with all sorts of complicated keyboard ideas for Android, and am wondering whether there is some way I can put together (or if someone else has already!) a set of tools like:
procedure Keyboard(Auto / Show / Hide, Full / Numeric), with the extra bits
KeyboardOnShow : tNotifyEvent
KeyboardOffShow tNotifyEvent
I have been spoilt by Delphi for too long. With the advent of Android and FIremonkey the unintuitive and arcane have returned to computing with a vengeance!
Chester Wilson.
Hi Chester.. Can you give examples of how/when you would use these?
Hi Dave, I am struggling to implement the demo code. I get a red line underneath the DW.VKVertScrollbox in the uses clause. Apparently it can’t find the code. How can I solve this?
Your help is appreciated
Jo
Hi Jo,
If there’s a red line underneath the unit name in the uses clause, then the unit is not in the compiler path (IDE or Project). Please ensure your paths include that unit (like the demo does)
Not working on Android 12? I am using Delphi 11.1
There does some to be an issue on Android 12. I’ll revisit this if I have time. I have created an issue here: https://github.com/DelphiWorlds/Kastri/issues/103
Hi Dave, thanks for your article. I was trying your solution on a webbrowser component but it appears to misbehave but on other controls it works perfectly well. Could you be having a solution for that?