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

结果:

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

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

 

实例代码:

  1 unit Unit1;
  2 
  3 interface
  4 
  5 uses
  6   System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  7   FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ComboEdit,
  8   FMX.Edit, FMX.EditBox, FMX.NumberBox, FMX.DateTimeCtrls, FMX.ScrollBox,
  9   FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls,
 10   System.Math,//需要引入
 11   FMX.VirtualKeyboard,//需要引入
 12   FMX.Layouts;
 13 
 14 type
 15   TForm1 = class(TForm)
 16     VertScrollBox1: TVertScrollBox;
 17     Layout1: TLayout;
 18     Memo1: TMemo;
 19     Label1: TLabel;
 20     Button1: TButton;
 21     Edit1: TEdit;
 22     Edit2: TEdit;
 23     procedure FormCreate(Sender: TObject);
 24     procedure FormFocusChanged(Sender: TObject);
 25     procedure FormVirtualKeyboardHidden(Sender: TObject;
 26       KeyboardVisible: Boolean; const Bounds: TRect);
 27     procedure FormVirtualKeyboardShown(Sender: TObject;
 28       KeyboardVisible: Boolean; const Bounds: TRect);
 29   private
 30     //定义移位标记
 31     FKBBounds:TRectF;
 32     FNeedOffset: Boolean;
 33     procedure CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
 34     procedure RestorePosition;
 35     procedure UpdateKBBounds;
 36     { Private declarations }
 37   public
 38     { Public declarations }
 39   end;
 40 
 41 var
 42   Form1: TForm1;
 43 
 44 implementation
 45 
 46 {$R *.fmx}
 47 {$R *.NmXhdpiPh.fmx ANDROID}
 48 
 49 //赋值事件
 50 procedure TForm1.FormCreate(Sender: TObject);
 51 begin
 52   VertScrollBox1.OnCalcContentBounds := CalcContentBoundsProc;
 53 end;
 54 
 55 //每次焦点改变都要更新位置
 56 procedure TForm1.FormFocusChanged(Sender: TObject);
 57 begin
 58   UpdateKBBounds;
 59 end;
 60 
 61 //输入法隐藏时的处理
 62 procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject;
 63   KeyboardVisible: Boolean; const Bounds: TRect);
 64 begin
 65   FKBBounds.Create(0, 0, 0, 0);
 66   FNeedOffset := False;
 67   RestorePosition;
 68 end;
 69 
 70 //输入法显示时的处理
 71 procedure TForm1.FormVirtualKeyboardShown(Sender: TObject;
 72   KeyboardVisible: Boolean; const Bounds: TRect);
 73 begin
 74   FKBBounds := TRectF.Create(Bounds);
 75   FKBBounds.TopLeft := ScreenToClient(FKBBounds.TopLeft);
 76   FKBBounds.BottomRight := ScreenToClient(FKBBounds.BottomRight);
 77   UpdateKBBounds;
 78 end;
 79 
 80 //计算内容边界
 81 procedure TForm1.CalcContentBoundsProc(Sender: TObject;
 82   var ContentBounds: TRectF);
 83 begin
 84   if FNeedOffset and (FKBBounds.Top > 0) then
 85   begin
 86     ContentBounds.Bottom := Max(ContentBounds.Bottom, 2 * ClientHeight - FKBBounds.Top);
 87   end;
 88 end;
 89 
 90 //还原位置
 91 procedure TForm1.RestorePosition;
 92 begin
 93   VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, 0);
 94   Layout1.Align := TAlignLayout.Client;
 95   VertScrollBox1.RealignContent;
 96 end;
 97 
 98 //更新边界
 99 procedure TForm1.UpdateKBBounds;
100 var
101   LFocused : TControl;
102   LFocusRect: TRectF;
103 begin
104   FNeedOffset := False;
105   if Assigned(Focused) then
106   begin
107     LFocused := TControl(Focused.GetObject);
108     LFocusRect := LFocused.AbsoluteRect;
109     LFocusRect.Offset(VertScrollBox1.ViewportPosition);
110     if (LFocusRect.IntersectsWith(TRectF.Create(FKBBounds))) and
111        (LFocusRect.Bottom > FKBBounds.Top) then
112     begin
113       FNeedOffset := True;
114       Layout1.Align := TAlignLayout.Horizontal;
115       VertScrollBox1.RealignContent;
116       Application.ProcessMessages;
117       VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, LFocusRect.Bottom - FKBBounds.Top);
118     end;
119   end;
120   if not FNeedOffset then
121     RestorePosition;
122 end;
123 
124 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上的。

posted on 2015-09-04 14:28  疯狂delphi  阅读(3326)  评论(0编辑  收藏  举报

导航