FireMonkey应用Android端TWebBrowser被虚拟键盘遮挡问题求助
Hey there! I’ve wrestled with this exact problem in FireMonkey on Android before—iOS plays nice with TVerticalScrollBox, but Android’s keyboard handling has always been a bit finicky. Let’s go through a few proven solutions that should get your web-based inputs visible when the keyboard pops up:
1. Hook into Android’s Native Keyboard Events Directly
FireMonkey’s built-in scroll logic can fall short on Android, so going straight to the native Android APIs is often the most reliable fix. Here’s how to implement a keyboard listener:
- In your form’s
OnCreateevent, useTAndroidHelperto access the current Activity and root view of your form. - Attach an
OnGlobalLayoutListenerto the root view’sViewTreeObserver. This listener triggers whenever the screen layout changes (like when the keyboard appears/disappears). - In the listener, calculate the difference between the screen’s usable height and the current view height to determine if the keyboard is active and how tall it is.
- Adjust your
TVerticalScrollBox’sViewportPosition.Yto shift content up by the keyboard’s height, then reset it when the keyboard hides. - Don’t forget to remove the listener in the form’s
OnDestroyevent to avoid memory leaks.
Here’s a quick code snippet to get you started:
uses Androidapi.JNI.App, Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers; procedure TForm1.FormCreate(Sender: TObject); var LRootView: JView; LObserver: JViewTreeObserver; begin LRootView := TAndroidHelper.Activity.getWindow.getDecorView.getRootView; LObserver := LRootView.getViewTreeObserver; LObserver.addOnGlobalLayoutListener(TJOnGlobalLayoutListener.CreateAnonymous( procedure var LRect: JRect; LScreenHeight, LViewHeight, LKeyboardHeight: Integer; begin LRect := TJRect.JavaClass.init; LRootView.getWindowVisibleDisplayFrame(LRect); LScreenHeight := LRootView.getHeight; LViewHeight := LRect.bottom - LRect.top; LKeyboardHeight := LScreenHeight - LViewHeight; if LKeyboardHeight > LScreenHeight * 0.15 then // Threshold to detect keyboard VerticalScrollBox1.ViewportPosition := PointF(0, LKeyboardHeight) else VerticalScrollBox1.ViewportPosition := PointF(0, 0); end )); end;
2. Tweak FireMonkey Form & Component Properties
Sometimes small property adjustments can make a world of difference:
- Set your form’s
FullScreenproperty toFalse. This forces Android to resize the app window when the keyboard appears, instead of overlaying it (the default for full-screen apps). - Ensure your
TVerticalScrollBoxhasAlignset toClient, and theTWebBrowserinside it also usesAlign = ClientwithScrollBarsdisabled (let the scroll box handle scrolling). - Try setting the form’s
KeyboardTypeto match the input type your web content uses (e.g.,ktTextfor regular text inputs) to hint to Android how to adjust the layout.
3. Use JavaScript-to-Delphi Communication
Since your content lives inside TWebBrowser, you can leverage JavaScript to detect input focus events and notify your Delphi code to adjust the scroll position:
- Add this JavaScript to your web content to listen for input focus:
document.querySelectorAll('input, textarea, [contenteditable="true"]').forEach(el => { el.addEventListener('focus', () => { const inputTop = el.getBoundingClientRect().top; window.external.notify(`inputFocused:${inputTop}`); }); }); - In Delphi, handle the
TWebBrowser.OnNotifyevent to receive the message, then calculate how much to scroll theTVerticalScrollBoxto bring the input above the keyboard.
Final Notes
For RAD Studio 10.2.2, the native Android listener method (option 1) is usually the most consistent. FireMonkey’s Android layout handling improved in later versions, but 10.2.2 needs a little extra nudge to get keyboard behavior right.
内容的提问来源于stack exchange,提问作者Felipe Violante

