Sichtbarkeit der Eingabemethode verarbeiten

Wenn der Eingabefokus in ein bearbeitbares Textfeld hinein- oder aus diesem herausbewegt, blendet Android die Eingabe, z. B. die Bildschirmtastatur, entsprechend ein oder aus. Das System entscheidet auch, wie die UI und das Textfeld über der Eingabemethode angezeigt werden. Wenn beispielsweise der vertikale Platz auf dem Bildschirm begrenzt ist, kann das Textfeld den gesamten Platz oberhalb der Eingabemethode ausfüllen.

Für die meisten Apps sind diese Standardeinstellungen alles, was erforderlich ist. In einigen Fällen möchten Sie möglicherweise mehr Kontrolle über die Sichtbarkeit der Eingabemethode und deren Auswirkungen auf das Layout haben. In dieser Lektion wird erläutert, wie Sie die Sichtbarkeit der Eingabemethode steuern und darauf reagieren können.

Bildschirmtastatur anzeigen, wenn die Aktivität beginnt

Android lenkt den Fokus zwar auf das erste Textfeld in Ihrem Layout, wenn die Aktivität beginnt, die Bildschirmtastatur wird jedoch nicht angezeigt. Dieses Verhalten ist angemessen, da die Eingabe von Text möglicherweise nicht die Hauptaufgabe der Aktivität ist. Wenn jedoch die Eingabe von Text die Hauptaufgabe ist, z. B. auf einem Anmeldebildschirm, soll wahrscheinlich standardmäßig die Softtastatur angezeigt werden.

Damit die Eingabemethode angezeigt wird, wenn die Aktivität beginnt, fügen Sie dem Element <activity> das Attribut android:windowSoftInputMode mit dem Wert "stateVisible" hinzu. Beispiele:

<application ... >
    <activity
        android:windowSoftInputMode="stateVisible" ... >
        ...
    </activity>
   ...
</application>

Festlegen, wie die UI reagieren soll

Wenn die weiche Tastatur auf dem Bildschirm angezeigt wird, reduziert sich dadurch der für die Benutzeroberfläche der App verfügbare Platz. Das System entscheidet, wie der sichtbare Teil der Benutzeroberfläche angepasst wird, aber es kann sein, dass er nicht richtig ist. Geben Sie an, wie das System Ihre UI im verbleibenden Bereich anzeigen soll, um das beste Verhalten für Ihre App zu erzielen.

Wenn du deine bevorzugte Behandlung in einer Aktivität angeben möchtest, verwende das Attribut android:windowSoftInputMode im <activity>-Element deines Manifests mit einem der „Adjust“-Werte.

Wenn Sie beispielsweise dafür sorgen möchten, dass das System die Größe des Layouts an den verfügbaren Bereich anpasst, sodass alle Layoutinhalte zugänglich bleiben, auch wenn sie scrollen müssen, verwenden Sie "adjustResize":

<application ... >
   <activity
       android:windowSoftInputMode="adjustResize" ... >
       ...
   </activity>
   ...
</application>

Sie können die Anpassungsspezifikation mit der Anfänglichkeitsspezifikation für die Softtastatur aus dem vorherigen Abschnitt kombinieren:

<activity
    android:windowSoftInputMode="stateVisible|adjustResize" ... >
    ...
</activity>

Die Angabe von "adjustResize" ist wichtig, wenn die UI Steuerelemente enthält, auf die der Nutzer möglicherweise sofort nach oder während der Texteingabe zugreifen muss. Wenn Sie beispielsweise ein relatives Layout verwenden, um eine Schaltflächenleiste am unteren Bildschirmrand zu platzieren, wird mit "adjustResize" die Größe des Layouts so angepasst, dass die Schaltflächenleiste über der Softtastatur erscheint.

Bildschirmtastatur bei Bedarf anzeigen

Wenn es im Lebenszyklus Ihrer Aktivität eine Methode gibt, bei der die Eingabemethode sichtbar sein soll, können Sie sie mit InputMethodManager anzeigen lassen.

Bei der folgenden Methode wird beispielsweise ein View verwendet, bei dem der Nutzer etwas eingeben soll. Dann wird requestFocus() aufgerufen, um den Fokus zu legen. Anschließend wird showSoftInput() aufgerufen, um die Eingabemethode zu öffnen:

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);
   }
}

Die weiche Tastatur zuverlässig präsentieren

In bestimmten Situationen, z. B. beim Beginn einer Aktivität, kann die Verwendung von InputMethodManager.showSoftInput() zum Anzeigen der Softtastatur dazu führen, dass die Softwaretastatur für den Nutzer nicht sichtbar ist.

Die Sichtbarkeit der Bildschirmtastatur bei der Verwendung von showSoftInput() hängt von den folgenden Bedingungen ab:

  • Die Ansicht muss bereits mit der Softwaretastatur verbunden sein. Dies wiederum erfordert, dass das Fenster fokussiert ist und die Editoransicht den Ansichtsfokus mit View.requestFocus() anfordern muss.

  • Die Sichtbarkeit kann auch durch das Attribut android:windowSoftInputMode und die von showSoftInput() verwendeten Flags beeinflusst werden.

In bestimmten Anwendungsfällen, z. B. beim Beginn einer Aktivität, werden einige dieser erforderlichen Bedingungen nicht erfüllt. Das System betrachtet die Ansicht nicht als mit der Softwaretastatur verbunden, ignoriert den showSoftInput()-Aufruf und die Bildschirmtastatur ist für den Nutzer nicht sichtbar.

Damit die Softwaretastatur zuverlässig angezeigt wird, können Sie die folgenden Alternativen verwenden:

  • Empfohlen: Verwenden Sie WindowInsetsControllerCompat. Dieses Objekt zeigt die Softtastatur während Activity.onCreate() an, wie im folgenden Code-Snippet dargestellt. Der Aufruf wird in jedem Fall geplant, nachdem das Fenster fokussiert wurde.

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);
      });
    }
  }
}

Mit den Flags für die Laufzeitsichtbarkeit sorgfältig umgehen

Achten Sie beim Umschalten der Sichtbarkeit bei der Softtastatur während der Laufzeit darauf, dass bestimmte Flag-Werte nicht an diese Methoden übergeben werden. Wenn die Anwendung beispielsweise erwartet, dass die Softtastatur beim Aufrufen von View.getWindowInsetsController().show(ime()) in Activity.onCreate() während des Starts der Aktivität angezeigt wird, sollten die Anwendungsentwickler darauf achten, die Flags SOFT_INPUT_STATE_HIDDEN oder SOFT_INPUT_STATE_ALWAYS_HIDDEN beim ersten Start nicht zu setzen, falls die Software unerwartet ausgeblendet wird.

Das System blendet die Bildschirmtastatur normalerweise automatisch aus

In den meisten Fällen blendet das System die Bildschirmtastatur nicht aus. Dabei kann es sich um einen der folgenden Fälle handeln:

  • Der Nutzer schließt die Aufgabe im Textfeld ab.
  • Der Nutzer drückt bei der Zurück-Navigation die Zurück-Taste oder wischt mit Touch-Gesten.
  • Der Nutzer ruft eine andere App auf und hat das Flag SOFT_INPUT_STATE_HIDDEN oder SOFT_INPUT_STATE_ALWAYS_HIDDEN gesetzt, wenn die Ansicht stärker in den Fokus rückt.

Softtastatur auf Grundlage des vorherigen Systemverhaltens manuell ausblenden

Deine App muss die Bildschirmtastatur in einigen Situationen manuell ausblenden, z. B. wenn das Textfeld in View.OnFocusChangeListener.onFocusChange nicht mehr fokussiert wird. Setzen Sie diese Technik mit Bedacht ein. Das Schließen der Software beeinträchtigt die Nutzererfahrung unerwartet.

Wenn deine App die Softwaretastatur manuell ausblendet, musst du wissen, ob sie explizit oder implizit angezeigt wurde:

  • Es wird davon ausgegangen, dass die Software nach einem Aufruf von showSoftInput() explizit angezeigt wurde.

  • Umgekehrt wird davon ausgegangen, dass die weiche Tastatur in einer der folgenden Bedingungen implizit gezeigt wurde:

    • Das System zeigte beim Anwenden von android:windowSoftInputMode die Softtastatur an.
    • Ihre App hat SHOW_IMPLICIT an showSoftInput() übergeben.

Normalerweise blendet hideSoftInputFromWindow() die Bildschirmtastatur unabhängig davon aus, wie sie angefordert wurde, aber mit HIDE_IMPLICIT_ONLY kann es auf das Schließen einer implizit angeforderten Tastatur eingeschränkt werden.

Dialogfeld oder Overlay-Ansicht über der Bildschirmtastatur anzeigen

In einigen Situationen muss die Editoraktivität möglicherweise ein nicht bearbeitbares Dialogfeld oder Overlay-Fenster über der Softwaretastatur erstellen.

Für Ihre App gibt es einige Optionen, die in den folgenden Abschnitten beschrieben werden.

Zusammenfassend lässt sich sagen, dass Sie darauf achten müssen, dass die Fenster-Flags der Softtastatur, die auf das Fenster ausgerichtet sind, so gehandhabt werden, dass sie die folgenden Erwartungen hinsichtlich der vertikalen Anordnung (Z-Ebene) erfüllt:

  • Keine Markierungen (normale Groß-/Kleinschreibung): Hinter der Softtastaturebene, kann Text empfangen.
  • FLAG_NOT_FOCUSABLE: Wird auf der Ebene der Bildschirmtastatur eingeblendet, aber es kann keinen Text empfangen.
  • FLAG_ALT_FOCUSABLE_IM: Auf der Ebene der Softtastatur kann der Fokus fokussiert werden, ist aber nicht mit der Softwaretastatur verbunden. Außerdem werden alle Ansichten darunter daran gehindert, eine Verbindung zur Softtastatur herzustellen. Dies ist nützlich, um ein App-Dialogfeld einzublenden, das keine Texteingabe oberhalb der Ebene der Softtastatur verwendet.
  • FLAG_NOT_FOCUSABLE und FLAG_ALT_FOCUSABLE_IM: hinter der Ebene der Softtastatur, aber kein Text empfangen.
  • FLAG_NOT_FOCUSABLE und FLAG_NOT_TOUCH_MODAL: Oben auf der Bildschirmtastatur und zulassen, dass Touch-Ereignisse durch das Fenster auf die Softtastatur gelangen.

Dialogfeld erstellen

Verwenden Sie das Flag FLAG_ALT_FOCUSABLE_IM des Dialogfensters, um das Dialogfeld oberhalb der Bildschirmtastatur zu halten und zu verhindern, dass die Software in den Fokus rückt:

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();

Overlay-Ansicht erstellen

Erstellen Sie eine Overlay-Ansicht, indem Sie den Fenstertyp TYPE_APPLICATION_OVERLAY und das Fenster-Flag FLAG_ALT_FOCUSABLE_IM durch die Zielaktivität der Softtastatur angeben.

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);

Dialogfeld oder Ansicht unter der Bildschirmtastatur anzeigen

Ihre Anwendung muss möglicherweise ein Dialogfeld oder ein Fenster mit den folgenden Eigenschaften erstellen:

  • Wird unter der von einer Editoraktivität angeforderten Softtastatur angezeigt, sodass sie nicht von der Texteingabe beeinflusst wird.
  • Berücksichtigt Änderungen an der Größe der Einfügung der Softtastatur, um das Layout des Dialogfelds oder Fensters anzupassen.

In diesem Fall bietet Ihre App mehrere Optionen. In den folgenden Abschnitten werden diese Optionen beschrieben.

Dialogfeld erstellen

Erstellen Sie ein Dialogfeld, indem Sie sowohl das Fenster-Flag FLAG_NOT_FOCUSABLE als auch das Fenster-Flag FLAG_ALT_FOCUSABLE_IM festlegen:

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();

Overlay-Ansicht erstellen

Erstellen Sie eine Overlay-Ansicht, indem Sie sowohl das Fenster-Flag FLAG_NOT_FOCUSABLE als auch das Fenster-Flag FLAG_ALT_FOCUSABLE_IM festlegen:

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);