欢迎到  ① 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 &lt; 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的更多相关文章

  1. XE5 修复 安卓 输入法隐藏 后 无法退出的问题 3.1

    (****************************************************)(* *)(* 编写:爱吃猪头肉 & Flying Wang *)(* 上面的版权声 ...

  2. delphi XE5下安卓开发技巧

    delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...

  3. dex方法隐藏后的反编译和运行时 效果

    隐藏smali方法后 java源码: int b = fun2(); baksmali解释为: invoke-virtual                  {v1}, <int MainAc ...

  4. linux vi 中按了ctrl+s后没法退出

    linux vi 中按了ctrl+s后无法退出 Linux 中使用vi编辑文件 不小心按了Ctrl + S (习惯了) 结果终端就跟死了一样, 解决办法: Ctrl+Q

  5. 关于easyui隐藏后数据不能刷新??

    原因是div用display属性隐藏后不能重新加载table数据 解决方法:使用hide()方法在初始化时隐藏 $("#two").hide(); //点击按钮隐藏与显示表单域 $ ...

  6. 【问题解决方案】从 Anaconda Prompt 或 Jupyter Notebook 终端进入Python后重新退出到命令状态

    从 Anaconda Prompt 或 Jupyter Notebook 终端进入Python后重新退出到命令状态 退出Python:exit() 或者 Ctrl+z 例子一枚 默认打开的是3.7,需 ...

  7. display none隐藏后如果表单有数值,那么他的数值还存在!

    以前以为display:none后他的值就不存在了, display:none隐藏后如果表单有数值,那么他的数值还存在.(项目出了问题!!) <!DOCTYPE html PUBLIC &quo ...

  8. Html 使用技巧 -- 设置display属性可以使div隐藏后释放占用的页面空间

         div的visibility可以控制div的显示和隐藏,但是隐藏后页面显示空白: style="visibility: none;" document.getElemen ...

  9. ecmall用户登录后自动退出解决方法

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

随机推荐

  1. mallmold开源商城系统网银在线chinabank支付插件

    最近没事捣鼓项目,找了个轻型商城系统mallmold,用起来还觉的挺不错的,尤其是mallmold中文版,赞一个.中文版集成了大部分主流支付系统,但因是个人网站,没法获得对应的服务,最终选择了网银在线 ...

  2. hdu 5122

    只要一个数的后面有比它小的数,这个数就要移,于是从后往前一趟遍历,记录一下这些数的个数就可以了. #include"iostream" #include"stdio.h& ...

  3. Unity3D优化总结(一)

    1.如使用碰撞器,简单的模型尽量使用自带的碰撞器如BoxCollider,少使用Mesh Collider. 2.如要使用Mesh Collider,可以做一个专用的模型(尽量少网格)做为Mesh C ...

  4. iOS 循环引用

    1.循环引用一般是指:A持有B,B同时持有A,从而导致死循环无法释放对象. 2.一般循环引用出现在block和delegate中,而一般解决方法就是将self变成weakSelf(强引用变成弱引用), ...

  5. 查找Maven JAR坐标

    http://mvnrepository.com/ http://search.maven.org/

  6. C# 根据年月日获取星期几方法

    #region 根据年月日计算星期几(Label2.Text=CaculateWeekDay(2004,12,9);) /// <summary> /// 根据年月日计算星期几(Label ...

  7. 读取java目录中相同目录、相同名称的文件

    使用ClassLoader的getResources方法(注意,不是getResource,少了s),可获得指定文件的包含jar包名称的多个路径值,然后依次读取文件即可. 使用class,只能通过ge ...

  8. Codeforces554A:Kyoya and Photobooks

    A. Kyoya and Photobooks Time Limit: 2000ms Memory Limit: 262144KB 64-bit integer IO format: %I64d    ...

  9. selenium项目的实战经验

    以前学习selenium,最接近项目的经验就是写了百度首页和自己开发的一个小网站的脚本,当时觉得差不多可以了.然而这次项目实战才发现还是学到不少知识,毕竟这个网站的专业程度远超过我自己写的,而且复杂程 ...

  10. slick for play 使用原生sql查询以及拼接sql

    在play中用函数式框架slick来操作数据库是一件很爽的事情.但有时因为某些特殊场景又不得不用原生的sql了. 还好slick支持这种写法,可以看看slick官方文档,Slick Plain SQL ...