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上的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM