處理輸入法顯示設定

當輸入焦點移入或移出可編輯的文字欄位時,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 視為 忽略 showSoftInput() 呼叫, 而且使用者也不會看見螢幕鍵盤

如要確保螢幕鍵盤正確顯示,可以使用以下方式: 替代方案:

Kotlin

editText.requestFocus()
WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())

Java

editText.requestFocus();
WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());

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_HIDDENSOFT_INPUT_STATE_ALWAYS_HIDDEN 旗標 以防螢幕鍵盤意外隱藏。

系統通常會自動隱藏螢幕鍵盤

在大多數情況下,系統會負責隱藏螢幕鍵盤。這個 可以是下列任一情況:

  • 使用者在文字欄位中完成工作。
  • 使用者以返回瀏覽方式按下返回鍵或滑動手勢。
  • 使用者前往其他應用程式,且該應用程式已設定 SOFT_INPUT_STATE_HIDDENSOFT_INPUT_STATE_ALWAYS_HIDDEN 旗標 當檢視區塊獲得焦點時
,瞭解如何調查及移除這項存取權。

根據先前的系統行為手動隱藏螢幕鍵盤

應用程式在某些情況下必須手動隱藏螢幕鍵盤,例如 舉例來說,如果文字欄位未聚焦於 View.OnFocusChangeListener.onFocusChange。謹慎使用這項技巧 ;意外關閉螢幕鍵盤會對使用者體驗造成負面影響。

如果您的應用程式手動隱藏螢幕鍵盤,您必須瞭解 螢幕鍵盤是以「明確」或「隱含」的方式顯示:

  • 螢幕鍵盤經過明確顯示 對 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);