Android实例-解决虚拟键盘遮挡问题(XE8+小米2)

Android实例-解决虚拟键盘遮挡问题(XE8+小米2)

结果:

1.可以自动向上移动,来防遮挡,但同时发现个问题,如果是按硬件返回没有问题,要是点输入法(QQ、百度输入法)上的隐藏就不行了。

2.点击Edit2后出现输入法,点输入法上的隐藏后, 再点Edit2输入法不再显示。

实例代码:

 unit Unit1;

 interface

 uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ComboEdit,
FMX.Edit, FMX.EditBox, FMX.NumberBox, FMX.DateTimeCtrls, FMX.ScrollBox,
FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls,
System.Math,//需要引入
FMX.VirtualKeyboard,//需要引入
FMX.Layouts; type
TForm1 = class(TForm)
VertScrollBox1: TVertScrollBox;
Layout1: TLayout;
Memo1: TMemo;
Label1: TLabel;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormFocusChanged(Sender: TObject);
procedure FormVirtualKeyboardHidden(Sender: TObject;
KeyboardVisible: Boolean; const Bounds: TRect);
procedure FormVirtualKeyboardShown(Sender: TObject;
KeyboardVisible: Boolean; const Bounds: TRect);
private
//定义移位标记
FKBBounds:TRectF;
FNeedOffset: Boolean;
procedure CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
procedure RestorePosition;
procedure UpdateKBBounds;
{ Private declarations }
public
{ Public declarations }
end; var
Form1: TForm1; implementation {$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID} //赋值事件
procedure TForm1.FormCreate(Sender: TObject);
begin
VertScrollBox1.OnCalcContentBounds := CalcContentBoundsProc;
end; //每次焦点改变都要更新位置
procedure TForm1.FormFocusChanged(Sender: TObject);
begin
UpdateKBBounds;
end; //输入法隐藏时的处理
procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject;
KeyboardVisible: Boolean; const Bounds: TRect);
begin
FKBBounds.Create(, , , );
FNeedOffset := False;
RestorePosition;
end; //输入法显示时的处理
procedure TForm1.FormVirtualKeyboardShown(Sender: TObject;
KeyboardVisible: Boolean; const Bounds: TRect);
begin
FKBBounds := TRectF.Create(Bounds);
FKBBounds.TopLeft := ScreenToClient(FKBBounds.TopLeft);
FKBBounds.BottomRight := ScreenToClient(FKBBounds.BottomRight);
UpdateKBBounds;
end; //计算内容边界
procedure TForm1.CalcContentBoundsProc(Sender: TObject;
var ContentBounds: TRectF);
begin
if FNeedOffset and (FKBBounds.Top > ) then
begin
ContentBounds.Bottom := Max(ContentBounds.Bottom, * ClientHeight - FKBBounds.Top);
end;
end; //还原位置
procedure TForm1.RestorePosition;
begin
VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, );
Layout1.Align := TAlignLayout.Client;
VertScrollBox1.RealignContent;
end; //更新边界
procedure TForm1.UpdateKBBounds;
var
LFocused : TControl;
LFocusRect: TRectF;
begin
FNeedOffset := False;
if Assigned(Focused) then
begin
LFocused := TControl(Focused.GetObject);
LFocusRect := LFocused.AbsoluteRect;
LFocusRect.Offset(VertScrollBox1.ViewportPosition);
if (LFocusRect.IntersectsWith(TRectF.Create(FKBBounds))) and
(LFocusRect.Bottom > FKBBounds.Top) then
begin
FNeedOffset := True;
Layout1.Align := TAlignLayout.Horizontal;
VertScrollBox1.RealignContent;
Application.ProcessMessages;
VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, LFocusRect.Bottom - FKBBounds.Top);
end;
end;
if not FNeedOffset then
RestorePosition;
end; end.

PS:

1.本实例来自官方demo(D:\DelphiXE8\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\Object Pascal\Mobile Samples\User Interface\ScrollableForm)。

2.控件布局是VertScrollBox1、Layout1,之后的控件都是在Layout1上的。

上一篇:iOS 键盘遮挡输入 解决办法


下一篇:.NET 4.5+项目迁移.NET Core的问题记录