修正 XE5 Android 键盘三个问题
16lz
2021-01-23
说明:XE5 在 Android 平台上存在这一些键盘操作的问题,目前发现有下列几种:
- 按键盘上的隐藏键后,无法按上一页(需要修改 XE5 源码「FMX.VirtualKeyboard.Android.pas」)。
- 按键盘上的隐藏键后,无法触发 OnVirtualKeyboardHidden事件。
- 关闭键盘后,再点一次无法显示键盘(大部份机子都有这个问题,实测 Nexus 7 II 没有这个问题)。
适用:Delphi XE5 update 2
参考:此修正方法是参考「完美解决XE5安卓下虚拟键盘隐藏没有事件的BUG。」在此感谢。
源码下载:修正XE5_Android键盘三个问题.zip
目前发现的键盘问题,需要修改 XE5 源码「FMX.VirtualKeyboard.Android.pas」才能修正,改好的档案已经放在上面源码 zip 里,改动内容如下({+++>}内为增加的部份{<+++}):
FMX.VirtualKeyboard.Android.pas
{+++>}function ObtainKeyboardRect: TRect;var ContentRect, TotalRect: JRect;begin ContentRect := TJRect.Create; TotalRect := TJRect.Create; MainActivity.getWindow.getDecorView.getWindowVisibleDisplayFrame(ContentRect); MainActivity.getWindow.getDecorView.getDrawingRect(TotalRect); Result := TRectF.Create(ConvertPixelToPoint(TPointF.Create(TotalRect.left, TotalRect.top + ContentRect.height)), ConvertPixelToPoint(TPointF.Create(TotalRect.right, TotalRect.bottom))).Truncate;end;{<+++}function TVirtualKeyboardAndroid.GetVirtualKeyBoardState: TVirtualKeyBoardState;begin if FError then Result := [vksError] else Result := []; if IsAutoShow then Result := Result + [vksAutoShow]; if not FError then begin{+++>} // 这里只解决: 按键盘上的隐藏后, 无法再按上一页的问题 (按上一页后, 才会执行这里). if FState = vkbsVisible then if ObtainKeyboardRect.Height < 30 then SetState(TVirtualKeyboardAndroid.TvkbState.vkbsHidden);{<+++} if FState = vkbsVisible then Result := Result + [vksVisible]; end;end;
Main.pas
//------------------------------------------------------------------------------// 2014.04.02 by 龟山阿卍 QQ 1467948783 -// http://www.cnblogs.com/onechen/ -// -// 需修改 -// FMX.VirtualKeyboard.Android.pas -//------------------------------------------------------------------------------unit Main;interfaceuses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Platform, FMX.VirtualKeyboard.Android, FMX.VirtualKeyboard, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit, FMX.StdCtrls, FMX.Layouts, FMX.Memo;type TForm1 = class(TForm) ToolBar1: TToolBar; Label1: TLabel; VirtualKeyboardTimer: TTimer; Memo1: TMemo; Edit1: TEdit; procedure FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect); procedure FormVirtualKeyboardShown(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect); procedure VirtualKeyboardTimerTimer(Sender: TObject); procedure Edit1Click(Sender: TObject); private { private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.fmx}// 显示键盘function ShowVirtualKeyboard(const AControl: TFmxObject): Boolean;var Service1: IFMXVirtualKeyboardService;begin if (ObtainKeyboardRect.Height < 30) and TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(Service1)) then Result := Service1.ShowVirtualKeyboard(AControl) else Result := False;end;procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);begin Edit1.Text := 'Keyboard hidden!'; Memo1.Text := Format('W: %d H: %d', [Bounds.Width, Bounds.Height]); VirtualKeyboardTimer.Enabled := False; // 关闭检查键盘高度end;procedure TForm1.FormVirtualKeyboardShown(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);begin Edit1.Text := 'Keyboard shown!'; Memo1.Text := Format('W: %d H: %d', [Bounds.Width, Bounds.Height]); VirtualKeyboardTimer.Enabled := True; // 开启检查键盘高度end;procedure TForm1.VirtualKeyboardTimerTimer(Sender: TObject);var R: TRect;begin // 检查键盘高度 < 30 代表键盘关闭. R := ObtainKeyboardRect; if R.Height < 30 then Self.OnVirtualKeyboardHidden(Sender, False, R);end;procedure TForm1.Edit1Click(Sender: TObject);begin // 在 TEdit 或 TMemo 需要用到键盘的控件, 加入下行, 才能确保关闭键盘后, 再点一次可以显示键盘. ShowVirtualKeyboard(TFmxObject(Sender));end;end.
「键盘上的隐藏键」是指下图所示位置:
更多相关文章
- Android输入法框架中按键消息的处理流程
- Android Binder源码阅读
- 将Fresco源码导入到Android Studio,Build失败的解决办法
- Android状态机StateMachine使用举例及源码解析
- eoe android客户端源码剖析(二)侧滑菜单SlidingMenu
- 解决 Android 软键盘挡住输入框的问题
- android 诸多源码工程下载