當輸入焦點移入或移出可編輯的文字欄位時,Android 會顯示或 隱藏輸入動作 (例如螢幕小鍵盤),例如 或適當。系統也會決定 UI 和文字欄位在上方顯示的方式 輸入方法舉例來說,如果螢幕的垂直空間是 因此文字欄位可能會填滿輸入法上方的所有空間。
對大多數應用程式而言,只需具備這些預設行為即可。在某些情況下 不過,您可能會想進一步掌控輸入法的瀏覽權限 對版面配置的影響。本課程將說明如何控制及回應 顯示輸入法
在活動開始時顯示螢幕鍵盤
儘管在顯示應用程式時,Android 會將焦點移至版面配置的第一個文字欄位 活動啟動後,不會顯示螢幕鍵盤。這是正常的行為 因為輸入文字可能不是活動的主要工作。不過, 輸入文字確實是主要工作,例如在登入畫面時 您可能希望預設顯示螢幕鍵盤
如要在活動啟動時顯示輸入法,請將
android:windowSoftInputMode
屬性對應至
<activity>
元素和 "stateVisible"
值。例如:
<application ... >
<activity
android:windowSoftInputMode="stateVisible" ... >
...
</activity>
...
</application>
指定 UI 的回應方式
當螢幕顯示螢幕鍵盤時,這會減少空間容量 。系統會決定如何調整 但可能有誤確保最佳行為 請指定您希望系統如何顯示使用者介面 剩餘空間。
如要在活動中宣告偏好的處理方式,請使用
資訊清單 <activity>
元素中的 android:windowSoftInputMode
屬性
請使用其中一項「調整項」輕鬆分配獎金
例如,為了確保系統能將版面配置調整為可用空間
空間 - 無論版面配置內容為何,
需要捲動畫面,請使用 "adjustResize"
:
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>
您可以將調整規格與初始螢幕鍵盤搭配使用 上一節所述的瀏覽權限規格:
<activity
android:windowSoftInputMode="stateVisible|adjustResize" ... >
...
</activity>
如果您的 UI 含有包含 "adjustResize"
的控制項
使用者可能需要在輸入文字後或執行後立即存取檔案。適用對象
舉例來說,如果您使用相對版面配置將按鈕列放在底部
使用 "adjustResize"
可調整版面配置大小,讓按鈕列顯示在畫面上
就在螢幕鍵盤上方。
隨選顯示螢幕鍵盤
如果活動生命週期中有想確保
顯示方式,您可以使用
InputMethodManager
敬上
以便顯示。
舉例來說,下列方法會使用
預期使用者前往的 View
輸入內容、通話
按下 requestFocus()
即可提供
焦點,然後呼叫 showSoftInput()
以開啟輸入法:
Kotlin
fun showSoftKeyboard(view: View) { if (view.requestFocus()) { val imm = getSystemService(InputMethodManager::class.java) imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) } }
Java
public void showSoftKeyboard(View view) { if (view.requestFocus()) { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } }
穩定顯示螢幕鍵盤
在某些情況下 (例如活動開始時)
使用 InputMethodManager.showSoftInput()
顯示螢幕鍵盤
可能會導致使用者看不到螢幕鍵盤。
使用 showSoftInput()
時,螢幕鍵盤的顯示設定保持穩定
並符合下列條件:
檢視畫面必須連線至螢幕鍵盤。( 需要聚焦的視窗和編輯器 用來要求檢視區塊焦點
View.requestFocus()
)。顯示設定也可能受
android:windowSoftInputMode
影響showSoftInput()
使用的屬性和標記。
在某些情況下 (例如活動開始時),其中一些
不符合必要條件。系統不會將 View 視為
忽略 showSoftInput()
呼叫,
而且使用者也不會看見螢幕鍵盤
如要確保螢幕鍵盤正確顯示,可以使用以下方式: 替代方案:
- (建議做法) 使用
WindowInsetsControllerCompat
。這個物件 在Activity.onCreate()
期間顯示螢幕鍵盤,如 下列程式碼片段。通話保證排定在時間過後 焦點。
Kotlin
editText.requestFocus() WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())
Java
editText.requestFocus(); WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
- 發布可執行項目。確保應用程式等到收到
呼叫前從
View.onWindowFocusChanged()
發生的視窗焦點事件showSoftInput()
。
Kotlin
class MyEditText : EditText() { ... override fun onWindowFocusChanged(hasWindowFocus: Boolean) { if (hasWindowFocus) { requestFocus() post { val imm: InputMethodManager = getSystemService(InputMethodManager::class.java) imm.showSoftInput(this, 0) } } } }
Java
public class MyEditText extends EditText { ... @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if (hasWindowFocus) { requestFocus(); post(() -> { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(this, 0); }); } } }
謹慎處理執行階段瀏覽權限標記
在執行階段切換螢幕鍵盤顯示設定時,請小心不要通過
標記值至這些方法中。舉例來說,如果應用程式預期
撥打電話時會顯示螢幕鍵盤
Activity.onCreate()
期間:View.getWindowInsetsController().show(ime())
,時間範圍:
活動啟動後,應用程式開發人員應謹慎不要
SOFT_INPUT_STATE_HIDDEN
或 SOFT_INPUT_STATE_ALWAYS_HIDDEN
旗標
以防螢幕鍵盤意外隱藏。
系統通常會自動隱藏螢幕鍵盤
在大多數情況下,系統會負責隱藏螢幕鍵盤。這個 可以是下列任一情況:
- 使用者在文字欄位中完成工作。
- 使用者以返回瀏覽方式按下返回鍵或滑動手勢。
- 使用者前往其他應用程式,且該應用程式已設定
SOFT_INPUT_STATE_HIDDEN
或SOFT_INPUT_STATE_ALWAYS_HIDDEN
旗標 當檢視區塊獲得焦點時
根據先前的系統行為手動隱藏螢幕鍵盤
應用程式在某些情況下必須手動隱藏螢幕鍵盤,例如
舉例來說,如果文字欄位未聚焦於
View.OnFocusChangeListener.onFocusChange
。謹慎使用這項技巧
;意外關閉螢幕鍵盤會對使用者體驗造成負面影響。
如果您的應用程式手動隱藏螢幕鍵盤,您必須瞭解 螢幕鍵盤是以「明確」或「隱含」的方式顯示:
螢幕鍵盤經過明確顯示 對
showSoftInput()
發出的呼叫。相反地,螢幕鍵盤則是在 下列其中一項條件:
- 系統在套用指令時
android:windowSoftInputMode
。 - 您的應用程式已將
SHOW_IMPLICIT
傳遞至showSoftInput()
。
- 系統在套用指令時
一般而言,hideSoftInputFromWindow()
會隱藏螢幕鍵盤,無論
要求方式,但依據 HIDE_IMPLICIT_ONLY
只能使用關閉隱含要求的螢幕鍵盤。
在螢幕鍵盤上方顯示對話方塊或重疊檢視畫面
在某些情況下,編輯者活動可能需要建立不可編輯的設定 對話方塊或螢幕鍵盤上方的重疊視窗。
應用程式有幾個選項,請參閱以下各節的說明。
簡單來說,務必正確處理螢幕鍵盤的視窗旗標 指定目標,使該回溯期滿足下列期望 關於垂直 (z 層) 排序:
- 無旗標 (一般情況):位於螢幕鍵盤圖層後方,可以接收文字。
FLAG_NOT_FOCUSABLE
敬上 :螢幕鍵盤圖層上方,但無法接收文字。FLAG_ALT_FOCUSABLE_IM
敬上 :在螢幕鍵盤圖層上方,可以聚焦,但不會連接 螢幕鍵盤。同時封鎖位於其下的所有視圖, 使其無法連結至 螢幕鍵盤。如要顯示不使用文字的應用程式對話方塊,這項功能就很實用 就在螢幕鍵盤圖層上方FLAG_NOT_FOCUSABLE
敬上 和FLAG_ALT_FOCUSABLE_IM
:螢幕鍵盤層後方,但無法接收文字。FLAG_NOT_FOCUSABLE
敬上 和FLAG_NOT_TOUCH_MODAL
:在螢幕鍵盤上方,並允許觸控事件「通過」 把視窗移到螢幕鍵盤上
建立對話方塊
使用 FLAG_ALT_FOCUSABLE_IM
對話方塊旗標,讓對話方塊持續顯示在螢幕鍵盤上方,以及
防止螢幕鍵盤成為焦點:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog on top of soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog on top of soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); mDialog.show();
建立疊加層檢視
建立疊加層檢視畫面,指定 TYPE_APPLICATION_OVERLAY
視窗類型和 FLAG_ALT_FOCUSABLE_IM
視窗標記。
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);
在螢幕鍵盤下方顯示對話方塊或檢視畫面
應用程式可能需要建立對話方塊或視窗, 屬性:
- 顯示在編輯者活動要求的螢幕鍵盤下方 就不會受到輸入文字的影響
- 保持螢幕鍵盤的插邊大小變更 調整對話方塊或視窗的版面配置。
就目前的狀況來說,您的應用程式有多種選項。後續章節 說明這些選項
建立對話方塊
同時設定 FLAG_NOT_FOCUSABLE
來建立對話方塊
視窗旗標和 FLAG_ALT_FOCUSABLE_IM
視窗旗標:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog behind soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog behind soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow() .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); mDialog.show();
建立疊加層檢視
設定 FLAG_NOT_FOCUSABLE
以建立疊加層檢視
視窗旗標和 FLAG_ALT_FOCUSABLE_IM
視窗旗標:
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);