你可以帮我如何在TEdit聚焦时隐藏(并再次显示)软键盘吗?
答案 0 :(得分:10)
我有一个解决方案:
在 .dpr 中将 VKAutoShowMode 设为从不
begin
Application.Initialize;
VKAutoShowMode := TVKAutoShowMode.Never;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
显示软键盘(例如,在TEdit.OnEnter事件中)
var
FService: IFMXVirtualKeyboardService;
begin
TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(FService));
if (FService <> nil) then
begin
FService.ShowVirtualKeyboard(Edit1);
Edit1.SetFocus;
end;
表格上的隐藏软键盘(Edit1仍将使用隐藏的软键盘聚焦)
var
FService: IFMXVirtualKeyboardService;
begin
TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(FService));
if (FService <> nil) then
begin
FService.HideVirtualKeyboard;
Edit1.SetFocus;
end;
醇>
答案 1 :(得分:4)
解决方案非常简单直接:
用您自己的原始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;
多数民众赞成。
答案 2 :(得分:3)
尝试在FMX.Types中使用变量VKAutoShowMode
答案 3 :(得分:2)
只需将以下代码行添加到控件的OnClick事件中即可。它似乎工作正常。
edit1.resetfocus; edit1.setfocus;
答案 4 :(得分:0)
刚刚找到了一个非常简单的解决方案。
在我的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;
如果用户再次点击文本字段,键盘会返回。
在Android上测试
答案 5 :(得分:-2)
尝试使用以下代码:
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);