1

我试过这个例子。但如果编辑字段的“密码”属性设置为 true,则它不起作用。知道如何使其与密码编辑字段一起使用吗?

4

1 回答 1

1

这是您尝试执行的操作的示例。只需将所有控件放入lyVKMain.

object frmBaseForm: TfrmBaseForm
  OnFocusChanged = FormFocusChanged
  OnVirtualKeyboardShown = FormVirtualKeyboardShown
  OnVirtualKeyboardHidden = FormVirtualKeyboardHidden
  DesignerMasterStyle = 0
  object vsVKScrollBox: TVertScrollBox
    Align = Contents
    Size.PlatformDefault = False
    TabOrder = 2
    Viewport.Width = 640.000000000000000000
    Viewport.Height = 480.000000000000000000
    object lyVKMain: TLayout
      Align = Client
      Size.PlatformDefault = False
      TabOrder = 0
    end
  end
end

和单位文件...

unit uForm;

interface

uses
  System.SysUtils,
  System.Types,
  System.UITypes,
  System.Classes,
  System.Variants,
  FMX.Types,
  FMX.Controls,
  FMX.Forms,
  FMX.Graphics,
  FMX.Dialogs,
  FMX.Layouts;

type
  TfrmBaseForm = class(TForm)
    vsVKScrollBox: TVertScrollBox;
    lyVKMain: TLayout;
    procedure FormFocusChanged(Sender: TObject);
    procedure FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
    procedure FormVirtualKeyboardShown(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
  private
    { Private declarations }
  public
    { Public declarations }
    FKBBounds: TRectF;
    FNeedOffset: Boolean;
    procedure CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
    procedure RestorePosition;
    procedure UpdateKBBounds;
    constructor Create(AOwner: TComponent); override;
  end;

var
  frmBaseForm: TfrmBaseForm;

implementation

uses
  System.Math;

{$R *.fmx}
{ TfrmBaseForm }

procedure TfrmBaseForm.CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
begin
  if FNeedOffset and (FKBBounds.Top > 0) then
  begin
    ContentBounds.Bottom := Max(ContentBounds.Bottom, 2 * ClientHeight - FKBBounds.Top);
  end;
end;

constructor TfrmBaseForm.Create(AOwner: TComponent);
begin
  inherited;
  vsVKScrollBox.OnCalcContentBounds := CalcContentBoundsProc;
end;

procedure TfrmBaseForm.FormFocusChanged(Sender: TObject);
begin
  UpdateKBBounds;
end;

procedure TfrmBaseForm.FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
begin
  FKBBounds.Create(0, 0, 0, 0);
  FNeedOffset := False;
  RestorePosition;
end;

procedure TfrmBaseForm.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 TfrmBaseForm.RestorePosition;
begin
  vsVKScrollBox.ViewportPosition := PointF(vsVKScrollBox.ViewportPosition.X, 0);
  lyVKMain.Align := TAlignLayout.Client;
  vsVKScrollBox.RealignContent;
end;

procedure TfrmBaseForm.UpdateKBBounds;
var
  LFocused: TControl;
  LFocusRect: TRectF;
begin
  FNeedOffset := False;
  if Assigned(Focused) then
  begin
    LFocused := TControl(Focused.GetObject);
    LFocusRect := LFocused.AbsoluteRect;
    LFocusRect.Offset(vsVKScrollBox.ViewportPosition);
    if (LFocusRect.IntersectsWith(TRectF.Create(FKBBounds))) and (LFocusRect.Bottom > FKBBounds.Top) then
    begin
      FNeedOffset := True;
      lyVKMain.Align := TAlignLayout.Horizontal;
      vsVKScrollBox.RealignContent;
      Application.ProcessMessages;
      vsVKScrollBox.ViewportPosition := PointF(vsVKScrollBox.ViewportPosition.X, LFocusRect.Bottom - FKBBounds.Top);
    end;
  end;
  if not FNeedOffset then
    RestorePosition;
end;

end.
于 2015-05-06T05:12:02.827 回答