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 := 0;
  KeyboardRect := ObtainKeyboardRect;
  //目前设置为 低于 30 就算隐藏。
  if (KeyboardRect.Width < 30) or (KeyboardRect.Height < 30) 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 < 1 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;

转载于:https://www.cnblogs.com/flyingwang/p/3640069.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值