• 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:DelphiXE8UsersPublicDocumentsEmbarcaderoStudio15.0SamplesObject PascalMobile SamplesUser InterfaceScrollableForm)。

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

  • 相关阅读:
    C++优化和计算速度(碎碎念)
    架设一个p2p存储网络的问题(讨论)
    JAVA做敏感词统计——DFA 算法
    卸载Postman,用IntelliJ IDEA发起http请求
    LPC1788SDRAM调试
    ASP.NET网站大附件上传配置
    K2 Blackpearl中从数据库直接删除流程实例之K2Server表
    K2流程实例出错,切换到其他版本运行
    使用K2时提示未能加载文件或程序集Microsoft.IdentityModel等
    K2 Blackpearl中从数据库直接删除流程实例之K2ServerLog表
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/4781696.html
Copyright © 2020-2023  润新知