XE5 修复 安卓 输入法隐藏 后 无法退出的问题 3.2
欢迎到 ① FireMonkey[DELPHI XE5] 165232328 交流开发技术。
(****************************************************)
(*                         *)
(*     编写:爱吃猪头肉 & Flying Wang     *)
(*      上面的版权声明请不要移除。      *)
(*          2014-03-15          *)
(*                         *)
(****************************************************)
找到 XE5 安装的 
FMX.VirtualKeyboard.Android.pas
将他们另存到(复制到)其他目录,例如您的工程目录。
将新复制出的文件加入到您的工程中。
【第一步】
打开 FMX.VirtualKeyboard.Android.pas 找到
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
      Result := Result + [vksVisible];
  end;
end;
将上面的函数修改为
//Fix Error By 爱吃猪头肉 & Flying Wang
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 GetVirtualKeyboardHeight: Single;
var
KeyboardRect: TRect;
begin
Result := ;
KeyboardRect := ObtainKeyboardRect;
//目前设置为 低于 就算隐藏。
if (KeyboardRect.Width < ) or (KeyboardRect.Height < ) then
begin
exit;
end;
Result := KeyboardRect.Height;
end; procedure ProcessVirtualKeyboardEvent;
var
VirtualKeyboard: IFMXVirtualKeyboardService;
VirtualKeyboardAndroid: TVirtualKeyboardAndroid;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService,
IInterface(VirtualKeyboard)) then
begin
VirtualKeyboardAndroid := TVirtualKeyboardAndroid(VirtualKeyboard);
VirtualKeyboardAndroid.GetVirtualKeyBoardState;
end;
end; function HideInputForFixVirtualKeyboradEvent :Boolean;
var
VirtualKeyboard: IFMXVirtualKeyboardService;
VirtualKeyboardAndroid: TVirtualKeyboardAndroid;
TextView: JFMXTextEditorProxy;
begin
Result := False;
try
Screen.ActiveForm.Focused := nil;
if TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService,
IInterface(VirtualKeyboard)) then
begin
VirtualKeyboardAndroid := TVirtualKeyboardAndroid(VirtualKeyboard);
end
else
begin
exit;
end;
TextView := MainActivity.getTextEditorProxy;
CallInUIThread(
procedure
begin
TextView.setFocusable(false);
TextView.setFocusableInTouchMode(false);
end);
Result := True;
except
Application.HandleException(Screen.ActiveForm);
end;
end; function TVirtualKeyboardAndroid.GetVirtualKeyboardState: TVirtualKeyboardState;
var
KeyboardRect: TRect;
begin
if FError then
Result := [vksError]
else
Result := [];
if IsAutoShow then
Result := Result + [vksAutoShow];
if not FError then
begin
if (FState = vkbsVisible) then
begin
if GetVirtualKeyboardHeight < then
begin
KeyboardRect := ObtainKeyboardRect;
TThread.Synchronize(nil,
procedure
begin
SetState(TVirtualKeyboardAndroid.TvkbState.vkbsHidden);
TMessageManager.DefaultManager.SendMessage(Self, TVKStateChangeMessage.Create(False, KeyboardRect), True);
end);
end;
end;
if FState = vkbsVisible then
Result := Result + [vksVisible];
end;
end;
缺点:我的山寨机上 26 的高度就没有输入法了。但是不知道其他的机器是多少。
事实上,只检查高度就可以,为了安全起见,才 高度 宽度 都检查的。
【第二步】
然后到 文件的前面(implementation 之前),定义
///	<summary>
///	  When < 1, it means VirtualKeyBoard Hided.
///	</summary>
function GetVirtualKeyBoardHeight: Single;
///	<summary>
///	  <para>
///	    Use a timer to call me. it will fix VirtualKeyboard Hide Message.
///	  </para>
///	  <para>
///	    用一个 TIMER 调用本函数,可以修复虚拟键盘的隐藏消息。
///	  </para>
///	</summary>
procedure ProcessVirtualKeyboardEvent;
///	<summary>
///	  强制输入控件隐藏输入。
///	</summary>
function HideInputForFixVisualKeyboradEvent :Boolean;
下面是【使用方法】。
1. 放一个 Timer 例如叫 TimerForVKeyborad。300ms 一次。
procedure TForm1.TimerForVKeyboradTimer(Sender: TObject);
begin
{$IFDEF ANDROID}
  ProcessVisualKeyboradEvent;
{$ENDIF}
end;
2. 完成如下事件。其实完全可以对每个输入框的按下事件处理。参考 4 。
procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
begin
  Memo1.Lines.Add('键盘隐藏了');
  Memo1.GoToTextEnd;
  if Focused <> Edit1.AsIControl then //这是为了配合 Edit1 的按下事件做的判断。
    Focused := nil; //这个代码其实也可以。
//{$IFDEF ANDROID}
//  HideInputForFixVisualKeyboradEvent;
//{$ENDIF}
end;
3. 完成如下事件。
procedure TForm1.FormVirtualKeyboardShown(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
begin
  Memo1.Lines.Add('键盘显示了');
  Memo1.GoToLineEnd;
end;
4 或者对每个输入框的按下事件处理。
uses
  FMX.Platform,
  FMX.VirtualKeyboard;
procedure TForm1.Edit1Click(Sender: TObject);
var
  VirtualKeyboard: IFMXVirtualKeyboardService;
begin
{$IFDEF ANDROID}
  //当没有选中自己的时候不自动弹出。
  if Focused <> Edit1.AsIControl then exit;
  if GetVirtualKeyboardHeight < 1 then
  begin
    if TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService,
      IInterface(VirtualKeyboard)) then
    begin
      if not (vksVisible in VirtualKeyboard.VirtualKeyBoardState) then
      begin
        if (vksAutoShow in VirtualKeyboard.VirtualKeyBoardState) then
          VirtualKeyboard.ShowVirtualKeyboard(Edit1);
      end;
    end;
  end;
{$ENDIF}
end;
XE5 修复 安卓 输入法隐藏 后 无法退出的问题 3.2的更多相关文章
- XE5 修复 安卓 输入法隐藏 后 无法退出的问题 3.1
		
(****************************************************)(* *)(* 编写:爱吃猪头肉 & Flying Wang *)(* 上面的版权声 ...
 - delphi XE5下安卓开发技巧
		
delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...
 - dex方法隐藏后的反编译和运行时 效果
		
隐藏smali方法后 java源码: int b = fun2(); baksmali解释为: invoke-virtual {v1}, <int MainAc ...
 - linux vi 中按了ctrl+s后没法退出
		
linux vi 中按了ctrl+s后无法退出 Linux 中使用vi编辑文件 不小心按了Ctrl + S (习惯了) 结果终端就跟死了一样, 解决办法: Ctrl+Q
 - 关于easyui隐藏后数据不能刷新??
		
原因是div用display属性隐藏后不能重新加载table数据 解决方法:使用hide()方法在初始化时隐藏 $("#two").hide(); //点击按钮隐藏与显示表单域 $ ...
 - 【问题解决方案】从 Anaconda Prompt 或 Jupyter Notebook 终端进入Python后重新退出到命令状态
		
从 Anaconda Prompt 或 Jupyter Notebook 终端进入Python后重新退出到命令状态 退出Python:exit() 或者 Ctrl+z 例子一枚 默认打开的是3.7,需 ...
 - display none隐藏后如果表单有数值,那么他的数值还存在!
		
以前以为display:none后他的值就不存在了, display:none隐藏后如果表单有数值,那么他的数值还存在.(项目出了问题!!) <!DOCTYPE html PUBLIC &quo ...
 - Html 使用技巧 -- 设置display属性可以使div隐藏后释放占用的页面空间
		
div的visibility可以控制div的显示和隐藏,但是隐藏后页面显示空白: style="visibility: none;" document.getElemen ...
 - ecmall用户登录后自动退出解决方法
		
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
 
随机推荐
- JAVA自定义异常
			
创建自定义异常是为了表示应用程序的一些错误类型,为代码可能发生的一个或多个问题提供新含义. 可区分代码运行时可能出现的相似问题的一个或多个错误,或给出应用程序中一组错误的特定含义. //自定义异常类需 ...
 - 配置ssl访问(https)
			
转载自http://www.blogjava.net/stevenjohn/archive/2012/09/26/388600.html 简要记录主要步骤备忘 1.进入到jdk下的bin目录 2.输入 ...
 - JavaScript之闭包就是个子公司
			
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有 ...
 - hibernate关联关系笔记
			
Hibernate关联关系笔记 单向N:1 * 有连接表:在N方使用<join>/<many-to-one>.1方无需配置与之关联的持久化类. * 没有连接表:在N方使用& ...
 - mysql在同一个表上查询和更新
 - awk之特征相同行的合并 ~转
			
awk之特征相同行的合并 文本: 1001 hisk01 1001 hisk02 1001 hisk03 1002 hisk04 1002 hisk05 1002 hisk06 1003 ...
 - 一个简易的四则运算单元...(15.12.15 BUG更新)
			
网上找的, 没有作者信息, 只能在这里感谢一下了, 支持标准写法的四则运算 --2015-12-15 修改了一个内存泄漏的BUG - Pop方法没有释放申请的内存 unit Base.Calculat ...
 - Source Insight下提示未完整安装的问题
			
网上的破解版的注册表文件都是针对32位系统的,所以在64位系统里运行根本无法破解.下面分别贴出这俩系统里的破解文件. 使用方法: 分别复制对应系统的内容,新建文本文档,将内容粘贴进去,重命名为.reg ...
 - How to install starDIct on suse OS?
			
1. Access page http://code.google.com/p/stardict-3/ to download starDict package or use zypper in to ...
 - ax Mail
			
SysMailer mailer = new SysMailer(); SysEmailParameters parameters = SysEmailParameters::find(); ; tr ...