線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1618
推到 Plurk!
推到 Facebook!

如何移動被visualkeyboard遮蔽的欄位

 
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2014-11-13 22:56:03 IP:118.160.xxx.xxx 未訂閱
這段是由 embd 的範例所引用的發佈的, 我再加以改良, 過程有點複雜, 但在我的 app 中是可以讓Edit 不被虛擬鍵盤(以下簡稱vkb)遮蔽
程式的部份如下, 分別宣告

private
F_VK_Service : IFMXVirtualKeyboardService;
procedure RestorePosition;

...

implementation

// 自定
procedure TForm1.RestorePosition;
begin
VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, 0);
VertScrollBox1.Align := TAlignLayout.Client;
VertScrollBox1.RealignContent;
end;

procedure TForm_ULpic.FormCreate(Sender: TObject);
TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService, IInterface(F_VK_Service));
// 單一edit键盤關閉後不能彈出問題的解决方法
// VKAutoShowMode := TVKAutoShowMode.vkasAlways;
// if (F_VK_Service <> nil) and (TVirtualKeyboardState.Visible in F_VK_Service.VirtualKeyBoardState) then
...
end;


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

// shown event
procedure TForm1.Form VirtualKeyboardShown(Sender: TObject;
KeyboardVisible: Boolean; const Bounds: TRect);
procedure 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;
VertScrollBox1.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;
begin
FKBBounds := TRectF.Create(Bounds);
FKBBounds.TopLeft := ScreenToClient(FKBBounds.TopLeft);
FKBBounds.BottomRight := ScreenToClient(FKBBounds.BottomRight);
UpdateKBBounds;
end;


元件部份(沒很多時間, 僅用文字方式說明)

最外層 可拉一個 TRectangle 或 TLayout -> 設置 width height (或 client)

Rectangle 內一定放一個 TVertScrollBox, 設置為 Client (填滿 Rectangle)

假設有10個TEdit, 放進 TVertScrollBox 內
所以它們的關係是
Form->Rectangle->VertScrollBox->Edit1~Edit10
而 Edit1 至 Edit10 不要過 VertScrollBox 的範圍(即一個視窗內都可以看到 Edit)

接下來是重頭戲了,
1.
放一個 TLable 到 VertScrollBox 的最底層, 而且要超過 VertScrollBox 的高度(以下簡稱 vsb)
例如 vsb 的 Height 是 500
Edit1 ~ Edit 10 的Y座標分別是 10, 60, 110.... 460, 肯定 460 的 Edit10 絕對會被 vkb 擋到
但 460 又沒有超過 vsb 的 500(Height) 範圍外

2.放一組 Label 到 vsb 內, 但 Label1.Position.Y 一定要超過 500以上, 要超過多少, 視你的 Edit10 移到畫面上不被 vkb 遮住為主
如果看不懂我說的, 試著把 Y 調整後, 自行到真機跑過一次就明白了,
例如 Label1.Position.Y := 600

3. 當這樣指定後, 你可以發現, vsb 看的到10組Edit, 但 Label 因為在 600 位置, 所以看不到, 為什麼要這麼做,
你只要在 vsb 中用滾輪捲動一下, 就可以知道, 在設計期間, 它是可以捲動的,
這個動作很重要, 因為你必須讓 vsb 能具有捲動效果

4. 好了, 把程式丟到真機上吧女 接下來就等 "見證奇蹟" 的時刻了,
但我前面提過, 千萬不要把 Edit10 擺到超過 500 的位置, 會怎麼樣了, 自己去試吧! (要多試10來次, 原則上你就會明白我指的意思)
編輯記錄
P.D. 重新編輯於 2014-11-13 22:59:14, 註解 無‧
系統時間:2024-04-26 2:58:03
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!