Eingabekompatibilität auf großen Bildschirmen

Auf Geräten mit großen Bildschirmen interagieren Nutzer häufig mit Apps über eine Tastatur, Maus, ein Touchpad, einen Stift oder ein Gamepad. So ermöglichen Sie Ihrer App, Eingaben von externen Geräten zu akzeptieren:

  • Grundlegende Tastaturunterstützung testen, z. B. Strg+Z für „Rückgängig“, Strg+C für „Kopieren“ und Strg+S für „Speichern“. Eine Liste der Standardtastenkombinationen finden Sie unter Tastaturaktionen verarbeiten.
  • Erweiterte Tastaturunterstützung testen, z. B. die Navigation mit der Tabulatortaste und den Pfeiltasten, die Bestätigung der Texteingabe mit der Eingabetaste sowie das Abspielen und Pausieren in Media-Apps mit der Leertaste.
  • Grundlegende Mausinteraktionen testen, einschließlich Rechtsklick für das Kontextmenü, Symboländerungen beim Hovern und Mausrad- oder Touchpad-Scroll-Ereignisse bei benutzerdefinierten Komponenten.
  • App-spezifische Eingabegeräte testen, z. B. Stifte, Gamecontroller und MIDI-Controller für Musik-Apps.
  • Unterstützung für erweiterte Eingaben kann die App in Desktopumgebungen hervorheben. Beispiele: Touchpad als Crossfader für DJ-Apps, Mauszeigerfang für Spiele und Tastenkombinationen für Nutzer, die hauptsächlich die Tastatur verwenden.

Tastatur

Die Art und Weise, wie Ihre App auf die Tastatureingabe reagiert, trägt zur Nutzerfreundlichkeit auf großen Bildschirmen bei. Es gibt drei Arten von Tastatureingaben: Navigation, Tastendrücke und Tastenkombinationen.

Die Tastaturnavigation wird in Apps, die für die Touchbedienung optimiert sind, selten implementiert. Nutzer erwarten sie jedoch, wenn sie eine App verwenden und ihre Hände auf der Tastatur haben. Die Tastaturnavigation kann auf Smartphones, Tablets, Foldables und Desktopgeräten für Nutzer mit Beeinträchtigungen unerlässlich sein.

Bei vielen Apps werden die Navigation mit den Pfeiltasten und der Tabulatortaste automatisch vom Android-Framework übernommen. Beispielsweise ist ein Button standardmäßig fokussierbar und die Tastaturnavigation sollte im Allgemeinen ohne zusätzlichen Code funktionieren. Wenn Sie die Tastaturnavigation für Ansichten aktivieren möchten, die standardmäßig nicht fokussierbar sind, müssen Sie sie als fokussierbar markieren. Das kann programmatisch oder in XML erfolgen:

Kotlin

yourView.isFocusable = true

Java

yourView.setFocusable(true);

Alternativ können Sie das Attribut focusable in Ihrer Layoutdatei festlegen:

android:focusable="true"

Weitere Informationen finden Sie unter Fokusbehandlung.

Wenn der Fokus aktiviert ist, erstellt das Android-Framework eine Navigationszuordnung für alle fokussierbaren Ansichten basierend auf ihrer Position. Das funktioniert in der Regel wie erwartet und es ist keine weitere Entwicklung erforderlich. Wenn die Standardzuordnung für die Anforderungen einer App nicht korrekt ist, kann sie so überschrieben werden:

Kotlin

// Arrow keys
yourView.nextFocusLeftId = R.id.view_to_left
yourView.nextFocusRightId = R.id.view_to_right
yourView.nextFocusTopId = R.id.view_above
yourView.nextFocusBottomId = R.id.view_below
// Tab key
yourView.nextFocusForwardId = R.id.next_view

Java

// Arrow keys
yourView.setNextFocusLeftId(R.id.view_to_left);
yourView.setNextFocusRightId(R.id.view_to_left);
yourView.setNextFocusTopId(R.id.view_to_left);
yourView.setNextFocusBottomId(R.id.view_to_left);
// Tab key
yourView.setNextFocusForwardId(R.id.next_view);

Testen Sie den Zugriff auf jedes UI-Element Ihrer App ausschließlich über die Tastatur. Häufig verwendete Elemente sollten ohne Maus- oder Toucheingabe zugänglich sein.

Denken Sie daran, dass die Tastaturunterstützung für Nutzer mit Beeinträchtigungen unerlässlich sein kann.

Tastenanschläge

Für die Texteingabe, die von einer virtuellen Bildschirmtastatur (IME) verarbeitet wird, z. B. für ein EditText sollten sich Apps auf Geräten mit großem Display wie erwartet verhalten, ohne dass zusätzliche Entwicklungsarbeit erforderlich ist. Bei Tasteneingaben, die vom Framework nicht vorhergesehen werden können, müssen Apps das Verhalten selbst verarbeiten. Das gilt insbesondere für Apps mit benutzerdefinierten Ansichten.

Beispiele sind Chat-Apps, in denen Nachrichten mit der Eingabetaste gesendet werden, Medien-Apps, in denen die Wiedergabe mit der Leertaste gestartet und beendet wird, und Spiele, in denen die Bewegung mit den Tasten w, a, s und d gesteuert wird.

Die meisten Apps überschreiben den onKeyUp()-Callback und fügen das erwartete Verhalten für jeden empfangenen Tastencode hinzu:

Kotlin

kotlin override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }

Java

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_ENTER) {
        sendMessage();
        return true;
    } else if (KeyEvent.KEYCODE_SPACE){
        playOrPauseMedia();
        return true;
    } else {
        return super.onKeyUp(keyCode, event);
    }
}

Ein onKeyUp-Ereignis tritt auf, wenn eine Taste losgelassen wird. Durch die Verwendung des Callbacks müssen Apps nicht mehrere onKeyDown-Ereignisse verarbeiten, wenn eine Taste gedrückt oder langsam losgelassen wird. Spiele und Apps, die erkennen müssen, wann eine Taste gedrückt wird oder ob der Nutzer eine Taste gedrückt hält, können auf das onKeyDown-Ereignis warten und wiederholte onKeyDown-Ereignisse selbst verarbeiten.

Weitere Informationen finden Sie unter Tastaturaktionen verarbeiten.

Verknüpfungen

Bei Verwendung einer Hardwaretastatur werden gängige Tastenkombinationen erwartet, die die Tasten Strg, Alt, Umschalt und Meta enthalten. Wenn eine App keine Verknüpfungen implementiert, kann das für Nutzer frustrierend sein. Auch fortgeschrittene Nutzer schätzen Tastenkombinationen für häufig verwendete app-spezifische Aufgaben. Kurzbefehle erleichtern die Verwendung einer App und heben sie von Apps ohne Kurzbefehle ab.

Zu den gängigen Tastenkombinationen gehören Strg + S (Speichern), Strg + Z (Rückgängig) und Strg + Umschalt + Z (Wiederholen). Eine Liste der Standardschaltflächen finden Sie unter Tastaturaktionen verarbeiten.

Tastenkombinationen können aktiviert werden, indem dispatchKeyShortcutEvent() implementiert wird, um alle Tastenkombinationen (Alt, Strg, Umschalt und Meta) für einen bestimmten Tastencode abzufangen. So prüfen Sie, ob eine bestimmte Modifikatortaste gedrückt wird:

Kotlin

override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean {
  return when (event.keyCode) {
    KeyEvent.KEYCODE_O -> {
      openFile() // Ctrl+O, Shift+O, Alt+O
      true
    }
    KeyEvent.KEYCODE_Z-> {
      if (event.isCtrlPressed) {
        if (event.isShiftPressed) {
          redoLastAction() // Ctrl+Shift+Z pressed
          true
        } else {
          undoLastAction() // Ctrl+Z pressed
          true
        }
      }
    }
    else -> {
      return super.dispatchKeyShortcutEvent(event)
    }
  }
}

Java

@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
  if (event.getKeyCode() == KeyEvent.KEYCODE_O) {
      openFile(); // Ctrl+O, Shift+O, Alt+O
      return true;
  } else if(event.getKeyCode() == KeyEvent.KEYCODE_Z) {
      if (event.isCtrlPressed()) {
          if (event.isShiftPressed()) {
              redoLastAction();
              return true;
          }
          else {
              undoLastAction();
              return true;
          }
      }
  }
  return super.dispatchKeyShortcutEvent(event);
}

Wenn Sie den Tastenkombinationscode von der anderen Tasteneingabebehandlung (z. B. onKeyUp() und onKeyDown()) trennen, werden Modifikatortasten standardmäßig akzeptiert, ohne dass Sie in jedem Fall manuell Modifikatortastenprüfungen implementieren müssen. Wenn Sie alle Kombinationen von Modifikatortasten zulassen, kann das auch für Nutzer, die an andere Tastaturlayouts und Betriebssysteme gewöhnt sind, praktischer sein.

Sie können jedoch auch Verknüpfungen in onKeyUp() implementieren, indem Sie nach KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() oder KeyEvent.isAltPressed() suchen. Das kann einfacher zu verwalten sein, wenn das geänderte Schlüsselverhalten eher eine Änderung des App-Verhaltens als eine Tastenkombination ist. Beispiel: In Spielen bedeutet W „nach vorne gehen“ und Umschalt + W „nach vorne rennen“.

Kotlin

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
  return when(keyCode) {
    KeyEvent.KEYCODE_W-> {
      if (event.isShiftPressed) {
        if (event.isCtrlPressed) {
          flyForward() // Ctrl+Shift+W pressed
          true
        } else {
          runForward() // Shift+W pressed
          true
        }
      } else {
        walkForward() // W pressed
        true
      }
    }
    else -> super.onKeyUp(keyCode, event)
  }
}

Java

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_W) {
        if (event.isShiftPressed()) {
            if (event.isCtrlPressed()) {
                flyForward(); // Ctrl+Shift+W pressed
                return true;
            } else {
                runForward(); // Shift+W pressed
                return true;
            }
        } else {
            walkForward();
            return true;
        }
    }
    return super.onKeyUp(keyCode, event);
}

Weitere Informationen finden Sie unter Hilfe zu Tastenkombinationen.

Eingabestift

Viele Geräte mit großem Display werden mit einem Eingabestift geliefert. Android-Apps behandeln Stifteingaben als Touchscreen-Eingaben. Einige Geräte haben möglicherweise auch ein USB- oder Bluetooth-Zeichentablet, z. B. das Wacom Intuos. Android-Apps können Bluetooth-Eingaben, aber keine USB-Eingaben empfangen.

Ein Stift-Ereignis wird von View#onTouchEvent() oder View#onGenericMotionEvent() als Touchscreen-Ereignis gemeldet und enthält ein MotionEvent#getSource() vom Typ SOURCE_STYLUS.

Das MotionEvent-Objekt enthält Informationen zum Ereignis:

Historische Punkte

Android fasst Eingabeereignisse zusammen und stellt sie einmal pro Frame bereit. Ein Stylus kann Ereignisse mit einer viel höheren Frequenz als das Display melden. Wenn Sie Zeichen-Apps erstellen, sollten Sie mit den getHistorical APIs nach Ereignissen suchen, die möglicherweise in der jüngsten Vergangenheit liegen:

Handballenerkennung

Wenn Nutzer mit einem Eingabestift zeichnen, schreiben oder mit Ihrer App interagieren, berühren sie manchmal das Display mit der Handfläche. Das Touch-Ereignis (auf ACTION_DOWN oder ACTION_POINTER_DOWN festgelegt) kann an Ihre App gemeldet werden, bevor das System die unbeabsichtigte Berührung mit der Handfläche erkennt und ignoriert.

Unter Android werden Handflächen-Touch-Ereignisse durch Senden eines MotionEvent abgebrochen. Wenn Ihre App ACTION_CANCEL empfängt, brechen Sie die Geste ab. Wenn Ihre App ACTION_POINTER_UP empfängt, prüfen Sie, ob FLAG_CANCELED festgelegt ist. Wenn ja, brechen Sie die Geste ab.

Prüfen Sie nicht nur auf FLAG_CANCELED. Unter Android 13 (API‑Level 33) und höher legt das System FLAG_CANCELED für ACTION_CANCEL-Ereignisse fest. Bei niedrigeren Android-Versionen wird das Flag jedoch nicht festgelegt.

Android 12

Unter Android 12 (API-Level 32) und niedriger ist die Erkennung der Handballenabweisung nur für Touch-Ereignisse mit einem einzelnen Zeiger möglich. Wenn eine Handflächenberührung der einzige Zeiger ist, bricht das System das Ereignis ab, indem es ACTION_CANCEL für das Motion-Event-Objekt festlegt. Wenn andere Zeiger nicht aktiv sind, legt das System ACTION_POINTER_UP fest, was nicht ausreicht, um die Handballenabweisung zu erkennen.

Android 13

Unter Android 13 (API‑Level 33) und höher bricht das System das Ereignis ab, indem es ACTION_CANCEL und FLAG_CANCELED für das Bewegungsereignisobjekt festlegt, wenn eine Handflächenberührung der einzige Zeiger ist. Wenn andere Zeiger nicht verfügbar sind, legt das System ACTION_POINTER_UP und FLAG_CANCELED fest.

Wenn Ihre App ein Motion-Event mit ACTION_POINTER_UP empfängt, prüfen Sie, ob FLAG_CANCELED vorhanden ist, um festzustellen, ob das Ereignis auf eine Handflächenabweisung (oder eine andere Ereignisabbrechung) hinweist.

Notizen-Apps

ChromeOS hat einen speziellen Intent, der registrierte Notizen-Apps für Nutzer sichtbar macht. Wenn Sie eine App als Notizen-App registrieren möchten, fügen Sie Ihrem App-Manifest Folgendes hinzu:

<intent-filter>
    <action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Wenn eine App im System registriert ist, kann der Nutzer sie als Standard-Notizen-App auswählen. Wenn eine neue Notiz angefordert wird, sollte die App eine leere Notiz erstellen, die für die Eingabe mit dem Eingabestift bereit ist. Wenn der Nutzer ein Bild (z. B. einen Screenshot oder ein heruntergeladenes Bild) mit Anmerkungen versehen möchte, wird die App mit ClipData gestartet, das ein oder mehrere Elemente mit content://-URIs enthält. Die App sollte eine Notiz erstellen, in der das erste angehängte Bild als Hintergrundbild verwendet wird, und in einen Modus wechseln, in dem der Nutzer mit einem Eingabestift auf dem Bildschirm zeichnen kann.

Notiz-Intents ohne Stylus testen

So testen Sie, ob eine App ohne aktiven Eingabestift korrekt auf Notiz-Intents reagiert: Verwenden Sie dazu die folgende Methode, um die Notizoptionen unter ChromeOS anzuzeigen:

  1. In den Entwicklermodus wechseln und das Gerät beschreibbar machen
  2. Drücken Sie Strg + Alt + F2, um ein Terminal zu öffnen.
  3. Führen Sie den Befehl sudo vi /etc/chrome_dev.conf aus
  4. Drücken Sie i, um die Datei zu bearbeiten, und fügen Sie --ash-enable-palette in einer neuen Zeile am Ende der Datei hinzu.
  5. Drücken Sie zum Speichern die Esc-Taste, geben Sie :, w, q ein und drücken Sie die Eingabetaste.
  6. Drücken Sie Strg + Alt + F1, um zur regulären ChromeOS-Benutzeroberfläche zurückzukehren.
  7. Melden Sie sich ab und wieder an

Im Ablagebereich sollte jetzt ein Stiftmenü angezeigt werden:

  • Tippen Sie in der Ablage auf die Stift-Schaltfläche und wählen Sie Neue Notiz aus. Dadurch sollte eine leere Zeichennotiz geöffnet werden.
  • Erstelle einen Screenshot. Wählen Sie im Ablagefach Stift-Schaltfläche > Bildschirm aufnehmen aus oder laden Sie ein Bild herunter. In der Benachrichtigung sollte die Option Bild mit Anmerkungen versehen angezeigt werden. Dadurch sollte die App mit dem Bild gestartet werden, das annotiert werden soll.

Unterstützung für Maus und Touchpad

Die meisten Apps müssen in der Regel nur drei Ereignisse für große Displays verarbeiten: Rechtsklick, Hover und Drag-and-drop.

Rechtsklicken

Alle Aktionen, die dazu führen, dass in einer App ein Kontextmenü angezeigt wird, z. B. langes Berühren eines Listenelements, sollten auch auf Rechtsklickereignisse reagieren.

Um Rechtsklick-Ereignisse zu verarbeiten, müssen Apps ein View.OnContextClickListener registrieren:

Kotlin

yourView.setOnContextClickListener {
    showContextMenu()
    true
}

Java

yourView.setOnContextClickListener(v -> {
    showContextMenu();
    return true;
});

Weitere Informationen zum Erstellen von Kontextmenüs finden Sie unter Kontextmenü erstellen.

Mauszeiger hierher bewegen

Durch die Verarbeitung von Hover-Ereignissen können Sie das Layout Ihrer App optimieren und die Nutzerfreundlichkeit verbessern. Das gilt insbesondere für benutzerdefinierte Aufrufe:

Kotlin

// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener { view, _ ->
    addVisualHighlighting(true)
    view.pointerIcon =
        PointerIcon.getSystemIcon(view.context, PointerIcon.TYPE_HAND)
    true // Listener consumes the event.
}

Java

// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener((view, event) -> {
    addVisualHighlighting(true);
    view.setPointerIcon(
        PointerIcon.getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND)
    );
    return true; // Listener consumes the event.
});

Die beiden häufigsten Beispiele hierfür sind:

  • Nutzer darauf hinweisen, ob ein Element interaktiv ist, z. B. durch Ändern des Mauszeigersymbols, wenn es anklickbar oder bearbeitbar ist
  • Visuelles Feedback für Elemente in einer großen Liste oder einem großen Raster hinzufügen, wenn der Mauszeiger darauf bewegt wird

Drag-and-drop

In einer Umgebung mit Mehrfenstermodus erwarten Nutzer, dass sie Elemente per Drag-and-drop zwischen Apps verschieben können. Das gilt für Computer sowie für Tablets, Smartphones und Faltgeräte im Splitscreen-Modus.

Überlegen Sie, ob Nutzer wahrscheinlich Elemente in Ihre App ziehen. Bei Bildbearbeitungsprogrammen ist beispielsweise davon auszugehen, dass Nutzer Fotos in die App ziehen, bei Audioplayern, dass sie Audiodateien in die App ziehen, und bei Zeichenprogrammen, dass sie Fotos in die App ziehen.

Informationen zum Hinzufügen von Drag-and-drop-Unterstützung finden Sie unter Drag-and-drop aktivieren und im Blogpost Android on ChromeOS – Implementing Drag & Drop.

Besondere Überlegungen für ChromeOS

  • Denken Sie daran, die Berechtigung mit requestDragAndDropPermissions() anzufordern, um auf Elemente zuzugreifen, die von außerhalb der App hineingezogen wurden.
  • Ein Element muss das Flag View.DRAG_FLAG_GLOBAL haben, damit es in andere Anwendungen gezogen werden kann.

Erweiterte Unterstützung für Zeiger

Apps, die eine erweiterte Verarbeitung von Maus- und Touchpad-Eingaben erfordern, sollten einen View#onGenericMotionEvent() und verwenden Sie [MotionEvent.getSource()][], um zwischen SOURCE_MOUSE und SOURCE_TOUCHSCREEN zu unterscheiden.

Untersuchen Sie das MotionEvent-Objekt, um das erforderliche Verhalten zu implementieren:

  • Durch Bewegung werden ACTION_HOVER_MOVE-Ereignisse ausgelöst.
  • Schaltflächen generieren ACTION_BUTTON_PRESS- und ACTION_BUTTON_RELEASE-Ereignisse. Sie können den aktuellen Status aller Maus- und Touchpad-Tasten auch mit getButtonState() prüfen.
  • Beim Scrollen mit dem Mausrad werden ACTION_SCROLL-Ereignisse generiert.

Controller

Einige Android-Geräte mit großem Display unterstützen bis zu vier Controller. Verwende die Standard-APIs für Android-Gamecontroller, um Gamecontroller zu verarbeiten (siehe Gamecontroller unterstützen).

Die Tasten des Controllers werden nach einer gemeinsamen Zuordnung gemeinsamen Werten zugeordnet. Allerdings folgen nicht alle Hersteller von Controllern denselben Zuordnungskonventionen. Sie können die Nutzerfreundlichkeit deutlich verbessern, wenn Sie Nutzern die Auswahl verschiedener beliebter Controller-Mappings ermöglichen. Weitere Informationen findest du unter Gamepad-Tastendrücke verarbeiten.

Eingabeübersetzungsmodus

In ChromeOS ist standardmäßig ein Modus für die Eingabeübersetzung aktiviert. Bei den meisten Android-Apps sorgt dieser Modus dafür, dass die Apps in einer Desktopumgebung wie erwartet funktionieren. Beispiele hierfür sind das automatische Aktivieren des Scrollens mit zwei Fingern auf dem Touchpad, das Scrollen mit dem Mausrad und die Zuordnung von Rohkoordinaten des Displays zu Fensterkoordinaten. Im Allgemeinen müssen App-Entwickler keines dieser Verhaltensweisen selbst implementieren.

Wenn eine App benutzerdefiniertes Eingabeverhalten implementiert, z. B. eine benutzerdefinierte Zwei-Finger-Touchpad-Geste, oder diese Eingabeübersetzungen nicht die von der App erwarteten Eingabeereignisse liefern, können Sie den Eingabeübersetzungsmodus deaktivieren, indem Sie dem Android-Manifest das folgende Tag hinzufügen:

<uses-feature
    android:name="android.hardware.type.pc"
    android:required="false" />

Zusätzliche Ressourcen