2014年7月12日 星期六

FireMonkey - 行動裝置上虛擬鍵盤的出現與隱藏

在 Win32 的應用程式開發中, VCL 架構當中, 我們常常會在畫面上有多個 TEdit 或 TMemo 的時候, 設定這些元件的 TabOrder, 用以決定每個文字編輯元件的順序, 待使用者輸入文字後,按下Tab鍵,便可切換到下一個文字輸入元件。

在行動裝置上卻沒有所謂以Tab鍵進行文字輸入元件切換的功能,要不是在虛擬鍵盤或手寫輸入控制元件上緣有上一個、下一個的按鍵進行切換,就會直接在鍵盤或手寫輸入框裏有換行、完成的按鍵,待使用者按下之後切換到下一個輸入的文字框去。

不僅如此,在行動裝置上輸入文字時,還會因為虛擬鍵盤的出現,需要把畫面整個向上挪移,才不會有文字框被虛擬鍵盤擋住,使用者輸入了什麼都看不見的窘況。

在 FireMonkey 的 TEdit,TMemo,就是扮演文字輸入框的角色,然而遍尋這兩個元件的所有Event,卻也找不著要如何達成前述切換文字輸入框的相關事件,更別提要像obj-c提供個像是 textFieldBeginEdit 這樣的Delegate method來偵測虛擬鍵盤的出現了。

雖然在TEdit裡面有onChange,onKeyUp,onKeyDown,onTyping這些事件,但這些事件卻無法接收到虛擬鍵盤的Return被觸發的事件,當然Windows系統上的Return可以測得,但行動裝置的不行,所以很令人煩躁。

然而,在FireMonkey 中,還是能夠達到前述功能的,只是要多花一些功夫,稍微多幾個步驟就是了:

KillFocusByReturn
這個屬性(property)是 TEdit 的新屬性,在設定接受到虛擬鍵盤的 Return 值時,是否要停止編輯,並讓目前的TEdit 失去Focus,這個屬性預設值是false,我們要把它改設定成true。

這樣一來,按下虛擬鍵盤的Return時,虛擬鍵盤就會自動縮回去了,也就是該文字框完成了編輯。

 

















































































TEdit 與鍵盤相關的新屬性
                        
TEdit 的事件


onEnter 事件
在每一個TEdit的事件表裡面,都有 onEnter 跟 onExit 這兩個事件,可以偵測到行動裝置上,該欄位是否開始/結束編輯了」

我們得自己計算一下每個TEdit 進入編輯模式時,該TEdit會不會被擋到?以iPad 為例,iPad的虛擬鍵盤(橫向)高度約為250,所以我會在橫向畫面最底下的TEdit 的 onEnter 事件當中設定一個畫面座標向上挪移250的動作:

procedure THeaderFooterForm.Edit1Enter(Sender: TObject);
begin
   shiftY := -150;
end;

設定了-150 的Y軸位移量之後,接著要偵測虛擬鍵盤出現與消失的事件:onVirtualKeyboardShow, onVirtualKeyboardHidden 這兩個事件,別急,看完再去寫 code。

Form 的虛擬鍵盤顯示/隱藏事件

onVirtualKeyboardShow, onVirtualKeyboardHidden 這兩個事件並不是歸屬給單一 TEdit 或TMemo 的哦,它們是歸屬於 TForm 的事件。

所以,我們接下來要先點選 TForm 元件,找到 onVirtualKeyboardShow, onVirtualKeyboardHidden 這兩個事件,雙擊它們,來製作出處理這兩個事件的事件處理常式。

如果Form 的畫面是由一個 align 設定為全螢幕(alClient)的TTabControl 元件所構成的,則在 onVirtualKeyboardShow 這個事件裡,我們要先把 TTabControl 元件的 align 屬性改設定為 alNone,否則修改其Position.Y 就不會有任何效果。

出現虛擬鍵盤
輸入完畢以後, 恢復原位














接著,把TTabControl Position.Y 設定為 ShiftY,就會看到畫面向上移動,露出正在輸入當中的 TEdit 或 TMemo 了。

最後,onVirtualKeyboardHidden 的時候,只要把 Position.Y 設定為 0,畫面就會恢復正常了。


心得分享:每一個文字輸入框的 ShiftY 都是獨立的,不用去管其他文字框的位移量是多少,彼此並沒有交互作用。


範例程式: 下載點