【问题标题】:How to hide (and again show) soft keyboard while TEdit is in focus DELPHI XE7如何在 TEdit 处于焦点时隐藏(并再次显示)软键盘 DELPHI XE7
【发布时间】:2015-02-08 17:05:23
【问题描述】:

你能帮我如何在 TEdit 处于焦点时隐藏(并再次显示)软键盘

【问题讨论】:

  • 试过InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);?
  • 查看:[关闭/隐藏 Android 软键盘][1] [1]:stackoverflow.com/questions/1109022/…
  • 我需要DELPHI的解决方案

标签: android delphi firemonkey soft-keyboard delphi-xe7


【解决方案1】:

我有一个解决方案:

  1. .dpr 中将 VKAutoShowMode 设置为 从不

    begin
      Application.Initialize;
      VKAutoShowMode := TVKAutoShowMode.Never;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end. 
    
  2. 在表单上显示软键盘(例如在 TEdit.OnEnter 事件中)

    var
      FService: IFMXVirtualKeyboardService;
    begin
      TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(FService));
      if (FService <> nil) then
      begin
        FService.ShowVirtualKeyboard(Edit1);
        Edit1.SetFocus;
      end;
    
  3. 隐藏软键盘在表单上(Edit1 仍将使用隐藏的软键盘聚焦)

    var
      FService: IFMXVirtualKeyboardService;
    begin
      TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(FService));
      if (FService <> nil) then
      begin
        FService.HideVirtualKeyboard;
        Edit1.SetFocus;
      end;
    

【讨论】:

  • 谢谢,这个信息很好,适用于带有 android 的 Delphi XE7。但是,我有一个问题,这是简单的方法吗?
  • 目前是。 Embarcadero 致力于纠正这件事上的错误。修复应该会在 Delphi 的下一个版本中发布。
  • 不适用于 Delphi 10.2(东京)和 Android 6。键盘保持可见
【解决方案2】:

解决方案非常简单直接:

用你自己的包装原来的IFMXVirtualKeyboardService,并检查控件是否应该有一个虚拟键盘。

这是一个完整的包装器,不仅限于 Android

unit Common.FMX.VirtualKeyboardService;

interface

uses
  System.Classes,
  System.Generics.Collections,
  FMX.Types,
  FMX.VirtualKeyboard;

type
  TVirtualKeyboardService = class( TComponent, IFMXVirtualKeyboardService )
  private
    FObjects: TList<TFmxObject>;
    FOriginalService: IFMXVirtualKeyboardService;
    constructor Create( AOwner: TComponent );
    class constructor Create;
  protected
    function GetVirtualKeyboardState: TVirtualKeyboardStates;
    function HideVirtualKeyboard: Boolean;
    procedure SetTransientState( Value: Boolean );
    function ShowVirtualKeyboard( const AControl: TFmxObject ): Boolean;
    procedure Notification( AComponent: TComponent; Operation: TOperation ); override;
  public
    class function Current: TVirtualKeyboardService;
    destructor Destroy; override;

    procedure AddOverrideObject( AObject: TFmxObject );
    procedure RemoveOverrideObject( AObject: TFmxObject );
    function IsOverriddenObject( AObject: TFmxObject ): Boolean;
  private
    class var _current: TVirtualKeyboardService;
  end;

implementation

uses
  FMX.Forms,
  FMX.Platform,
  System.SysUtils;

{ TVirtualKeyboardService }

constructor TVirtualKeyboardService.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );

  FObjects := TList<TFmxObject>.Create;

  if TPlatformServices.Current.SupportsPlatformService( IFMXVirtualKeyboardService, FOriginalService ) then
  begin
    TPlatformServices.Current.RemovePlatformService( IFMXVirtualKeyboardService );
    TPlatformServices.Current.AddPlatformService( IFMXVirtualKeyboardService, Self );
  end;
end;

procedure TVirtualKeyboardService.AddOverrideObject( AObject: TFmxObject );
begin
  if Supports( AObject, IVirtualKeyboardControl ) and not FObjects.Contains( AObject ) then
  begin
    FObjects.Add( AObject );
    Self.FreeNotification( AObject );
  end;
end;

class constructor TVirtualKeyboardService.Create;
begin
  TVirtualKeyboardService._current := TVirtualKeyboardService.Create( Application );
end;

class function TVirtualKeyboardService.Current: TVirtualKeyboardService;
begin
  Result := TVirtualKeyboardService._current;
end;

destructor TVirtualKeyboardService.Destroy;
begin
  if Assigned( FOriginalService ) then
  begin
    TPlatformServices.Current.RemovePlatformService( IFMXVirtualKeyboardService );
    TPlatformServices.Current.AddPlatformService( IFMXVirtualKeyboardService, FOriginalService );
  end;
  FObjects.Free;
  inherited;
end;

function TVirtualKeyboardService.GetVirtualKeyboardState: TVirtualKeyboardStates;
begin
  Result := FOriginalService.VirtualKeyboardState;
end;

function TVirtualKeyboardService.HideVirtualKeyboard: Boolean;
begin
  Result := FOriginalService.HideVirtualKeyboard;
end;

function TVirtualKeyboardService.IsOverriddenObject( AObject: TFmxObject ): Boolean;
begin
  Result := FObjects.Contains( AObject );
end;

procedure TVirtualKeyboardService.Notification( AComponent: TComponent; Operation: TOperation );
begin
  inherited;
  if ( Operation = opRemove ) and ( AComponent is TFmxObject ) then
  begin
    RemoveOverrideObject( AComponent as TFmxObject );
  end;
end;

procedure TVirtualKeyboardService.RemoveOverrideObject( AObject: TFmxObject );
begin
  if FObjects.Contains( AObject ) then
  begin
    FObjects.Remove( AObject );
    Self.RemoveFreeNotification( AObject );
  end;
end;

procedure TVirtualKeyboardService.SetTransientState( Value: Boolean );
begin
  FOriginalService.SetTransientState( Value );
end;

function TVirtualKeyboardService.ShowVirtualKeyboard( const AControl: TFmxObject ): Boolean;
begin
  if IsOverriddenObject( AControl ) then
    begin
      HideVirtualKeyboard;
      Result := False;
    end
  else
    Result := FOriginalService.ShowVirtualKeyboard( AControl );
end;

end.

如果你想为你的控件禁用虚拟键盘,只需调用

uses
  Common.FMX.VirtualKeyboardService;

procedure TForm1.AfterConstruction;
begin
  inherited;
  TVirtualKeyboardService.AddOverrideObject( Edit1 );
end;

就是这样。

【讨论】:

    【解决方案3】:

    尝试在 FMX.Types 中使用变量 VKAutoShowMode

    【讨论】:

      【解决方案4】:

      只需在控件的 OnClick 事件中添加以下代码行。它似乎工作正常。

      edit1.resetfocus; edit1.setfocus;

      【讨论】:

      • 我在 Android 和 Windows FMX 上的 TSpinBox 上试过这个,而且它在很多时候都有效。
      【解决方案5】:

      刚刚找到了一个非常简单的解决方案。

      在我的 OnKeyDown 事件中,我正在检查 vkEnter 并执行一些代码。我想在完成后关闭键盘。

      只需将我的 TEdit 设置为未启用并再次返回,即:

      procedure TfrmMain.dtBarCodeKeyDown(Sender: TObject; var Key: Word;
        var KeyChar: Char; Shift: TShiftState);
      begin
        if Key = vkReturn then
          begin
            dtBarCode.Enabled := false; //kill the keyboard
            try
              LoadBarCode;
            finally
              dtBarCode.Enabled := true;
            end;
          end;
      end;
      

      如果用户再次点击文本字段,键盘就会恢复。

      在安卓上测试

      【讨论】:

        【解决方案6】:

        试试下面的代码:

        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        

        【讨论】:

        • 我需要DELPHI的解决方案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-17
        • 2018-07-16
        • 2015-08-10
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多