Eingabekompatibilität auf großen Bildschirmen

Auf Geräten mit großen Bildschirmen interagieren Nutzer häufiger über Tastatur, Maus, Touchpad, Eingabestift oder Gamepad mit Apps. So aktivieren Sie, dass Ihre App Eingaben von externen Geräten akzeptieren kann:

  • Grundlegende Tastaturunterstützung testen, z. B. Navigation mit Tabulatortaste und Pfeiltaste, Bestätigung der Eingabe von Eingabetastentext und Abspielen/Pausieren der Leertaste in Medien-Apps
  • Fügen Sie gegebenenfalls Standard-Tastenkombinationen hinzu, z. B. Strg + Z zum Rückgängigmachen und Strg + S zum Speichern.
  • Testen grundlegender Mausinteraktionen in Form von Rechtsklick für Kontextmenü, Symboländerungen beim Mouseover und Scroll-Ereignissen des Mausrads oder Touchpads bei benutzerdefinierten Ansichten
  • Test-App-spezifische Eingabegeräte wie Eingabestifte zum Zeichnen von Apps, Game-Controller für Spiele und MIDI-Controller für Musik-Apps
  • Erwägen Sie die erweiterte Eingabeunterstützung, um die App in Desktopumgebungen hervorzuheben. Beispielsweise können Sie das Touchpad als Cross-Fader für DJ-Apps, die Mausaufnahme für Spiele und umfangreiche Tastenkombinationen für Nutzer verwenden, die auf Tastaturen arbeiten.

Tastatur

Die Art und Weise, wie Ihre App auf Tastatureingaben reagiert, trägt zu einer guten Nutzerfreundlichkeit bei großen Bildschirmen bei. Es gibt drei Arten der Tastatureingabe: Navigation, Tastenanschläge und Tastenkombinationen.

Die Tastaturnavigation wird nur selten in berührungsorientierten Apps implementiert. Nutzer erwarten sie jedoch, wenn sie eine App verwenden und ihre Hände auf einer Tastatur haben. Sie kann auch für Nutzer mit Bedienungshilfen auf Smartphones, Tablets, faltbaren Geräten und Computern unverzichtbar sein.

Für viele Apps sind eine einfache Navigation mit Pfeiltasten und Tabs erforderlich, die größtenteils automatisch vom Android-Framework ausgeführt wird. Beispielsweise ist eine Ansicht einer Button standardmäßig fokussierbar und die Tastaturnavigation sollte im Allgemeinen ohne zusätzlichen Code funktionieren. Um die Tastaturnavigation für Ansichten zu aktivieren, die standardmäßig nicht fokussierbar sind, sollten Entwickler sie als fokussierbar markieren. Dies kann programmatisch oder in XML erfolgen, wie unten gezeigt. Weitere Informationen finden Sie unter Fokusbehandlung.

Kotlin

yourView.isFocusable = true

Java

yourView.setFocusable(true);

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

android:focusable="true"

Sobald der Fokus aktiviert ist, erstellt das Android-Framework eine Navigationszuordnung für alle fokussierbaren Ansichten auf der Grundlage ihrer Position. Das funktioniert in der Regel wie erwartet und es ist keine weitere Arbeit erforderlich. Wenn die Standardzuordnung für die Anforderungen einer Anwendung nicht geeignet 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);

Es empfiehlt sich, vor jedem Release nur mit der Tastatur auf alle Funktionen der App zuzugreifen. Die gängigsten Aktionen sollten ohne Maus oder Berührung leicht zugänglich sein.

Denken Sie daran, dass die Tastaturunterstützung für Nutzer mit Anforderungen an die Barrierefreiheit unverzichtbar sein kann.

Tastenanschläge

Bei Texteingaben, die über eine Bildschirmtastatur (IME) wie EditText verarbeitet werden, sollten Apps sich auf Geräten mit großen Bildschirmen wie erwartet verhalten, ohne dass der Entwickler etwas tun muss. Tastenanschläge, die vom Framework nicht erwartet werden können, müssen von den Anwendungen selbst verarbeitet werden. Dies gilt insbesondere für Apps mit benutzerdefinierten Ansichten.

Beispiele hierfür sind Chat-Apps, die die Eingabetaste zum Senden einer Nachricht verwenden, Medien-Apps, die die Wiedergabe mit der Leertaste starten und stoppen, und Spiele, die Bewegungen mit den Tasten w, a, s und d steuern.

Die meisten Apps überschreiben den onKeyUp()-Callback und fügen das erwartete Verhalten für jeden empfangenen Schlüsselcode hinzu, wie unten gezeigt:

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 ein Schlüssel freigegeben wird. Mit diesem Callback wird verhindert, dass Anwendungen mehrere onKeyDown-Ereignisse verarbeiten müssen, wenn ein Schlüssel langsam gedrückt oder wieder freigegeben wird. Spiele und Apps, die wissen möchten, wann eine Taste gedrückt wird, oder bei denen davon ausgegangen wird, dass Nutzer Tasten auf der Tastatur gedrückt halten, können nach dem onKeyDown()-Ereignis suchen und die wiederholten onKeyDown-Ereignisse selbst verarbeiten.

Weitere Informationen zur Tastaturunterstützung finden Sie unter Tastaturaktionen ausführen.

Verknüpfungen

Bei der Verwendung einer Hardwaretastatur werden gängige Tastenkombinationen für Strg, Alt und Umschalttaste erwartet. Werden sie in einer App nicht implementiert, kann das für die Nutzer frustrierend sein. Fortgeschrittene Nutzer schätzen auch Verknüpfungen für häufig verwendete appspezifische Aufgaben. Verknüpfungen erleichtern die Nutzung und unterscheiden sie von Apps ohne Verknüpfungen.

Einige gängige Tastenkombinationen sind Strg + S (Speichern), Strg + Z (Rückgängig machen) und Strg + Umschalttaste + Z (Wiederholen). Ein Beispiel für erweiterte Tastenkombinationen finden Sie in der Liste der Tastenkombinationen für den VLC Media Player.

Verknüpfungen können mit dispatchKeyShortcutEvent() implementiert werden. Dadurch werden alle Meta-Tastenkombinationen (Alt, Strg und Umschalttaste) für einen bestimmten Tastencode abgefangen. Verwenden Sie KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed(), KeyEvent.isAltPressed() oder KeyEvent.hasModifiers(), um nach einem bestimmten Metaschlüssel zu suchen.

Durch die Trennung von Tastenkombination von anderen Tastenanschlägen (z. B. onKeyUp() und onKeyDown()) lässt sich die Codeverwaltung vereinfachen. Außerdem werden Metatasten standardmäßig akzeptiert, ohne dass Metatasteprüfungen in jedem Fall manuell implementiert werden müssen. Außerdem ist es für Nutzer, die mit verschiedenen Tastaturlayouts und Betriebssystemen vertraut sind, praktischer, alle Tastenkombinationen zuzulassen.

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

Sie können auch Verknüpfungen in onKeyUp() implementieren. Suchen Sie dazu auf dieselbe Weise wie oben nach KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() oder KeyEvent.isAltPressed(). Dies kann einfacher gehalten werden, wenn das Meta-Verhalten eher eine Änderung des Anwendungsverhaltens als eine Verknüpfung darstellt. Beispiel: W bedeutet „vorwärts gehen“ und Umschalttaste + W „vorwärts laufen“.

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

Eingabestift

Auf vielen Geräten mit großen Bildschirmen ist ein Eingabestift installiert und Android-Apps verarbeiten dies als Eingabe über den Touchscreen. Einige Geräte haben möglicherweise auch eine USB- oder Bluetooth-Zeichentabelle, z. B. Wacom Intuos. Android-Apps können Bluetooth-Eingaben empfangen, funktionieren jedoch nicht mit der USB-Eingabe.

Ein Eingabestiftereignis wird über View.onTouchEvent() oder View.onGenericMotionEvent() als Touchscreen-Ereignis gemeldet und enthält einen MotionEvent.getSource() vom Typ SOURCE_STYLUS.

MotionEvent enthält auch zusätzliche Daten:

Historische Punkte

Android führt Eingabeereignisse zu Batches und stellt sie einmal pro Frame bereit. Ein Eingabestift kann Ereignisse in viel höheren Frequenzen als das Display melden. Beim Erstellen von Zeichen-Apps ist es wichtig, mithilfe der getHistorical APIs nach Ereignissen zu suchen, die vor Kurzem stattgefunden haben:

  • MotionEvent.getHistoricalX()
  • MotionEvent.getHistoricalY()
  • MotionEvent.getHistoricalPressure()
  • MotionEvent.getHistoricalAxisValue()

Ablehnung der Handfläche

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

Android bricht Palm Touch-Ereignisse ab, indem ein MotionEvent ausgelöst wird. Wenn Ihre Anwendung ACTION_CANCEL empfängt, brechen Sie die Bewegung ab. Wenn Ihre Anwendung ACTION_POINTER_UP empfängt, prüfen Sie, ob FLAG_CANCELED festgelegt ist. Brechen Sie die Bewegung in diesem Fall ab.

Nicht nur nach FLAG_CANCELED suchen. Ab Android 13 legt das System der Einfachheit halber FLAG_CANCELED für ACTION_CANCEL-Ereignisse fest, bei Vorgängerversionen jedoch nicht.

Android 12

Unter Android 12 (API-Level 32) und niedriger ist die Erkennung einer Handablehnung nur bei Einzelpunkt-Touch-Ereignissen möglich. Wenn nur eine Handfläche berührt wird, bricht das System das Ereignis ab, indem es ACTION_CANCEL für das Bewegungsereignisobjekt festlegt. Wenn andere Zeiger ausfallen, legt das System ACTION_POINTER_UP fest. Dieser Wert reicht nicht aus, um die Ablehnung der Handfläche zu erkennen.

Android 13

Unter Android 13 (API-Level 33) und höher bricht das System das Ereignis ab, wenn nur eine Handfläche berührt wird. Dazu werden ACTION_CANCEL und FLAG_CANCELED für das Bewegungsereignisobjekt festgelegt. Wenn andere Zeiger ausgefallen sind, legt das System ACTION_POINTER_UP und FLAG_CANCELED fest.

Immer wenn deine App ein Bewegungsereignis mit ACTION_POINTER_UP empfängt, suche nach FLAG_CANCELED, um festzustellen, ob das Ereignis auf eine Palmablehnung (oder eine andere Ereignisabsage) hinweist.

Notizen-Apps

ChromeOS hat einen speziellen Zweck, Nutzern registrierte Notizen-Apps zur Verfügung zu stellen. Um eine App als Notizen-App zu registrieren, fügen Sie dem Android-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 registriert ist, kann der Nutzer sie als Standard-Notizen-App auswählen. Wenn eine neue Notiz angefordert wird, sollte von der App eine leere Notiz erstellt werden, die über den Eingabestift eingegeben werden kann. Wenn der Nutzer einem Bild Anmerkungen hinzufügen möchte (z. B. einen Screenshot oder ein heruntergeladenes Bild), startet die App mit ClipData, die 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.

Notizen-Intents ohne Eingabestift testen

Mit der folgenden Methode können Sie unter ChromeOS testen, ob eine App korrekt auf Notizen-Intents reagiert:

  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 --ash-enable-palette in eine neue Zeile am Ende der Datei einzufügen
  5. Drücken Sie zum Speichern die Esc-Taste, geben Sie dann :, 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. Abmelden und wieder anmelden

In der Ablage sollte jetzt ein Eingabestiftmenü angezeigt werden:

  • Tippe in der Ablage auf die Eingabestift-Schaltfläche und wähle Neue Notiz aus. Dadurch sollte eine leere Zeichnungsnotiz geöffnet werden.
  • Machen Sie einen Screenshot. Wählen Sie in der Ablage Eingabestift-Schaltfläche > Bildschirm aufnehmen aus oder laden Sie ein Bild herunter. In der Benachrichtigung sollte die Option „Bild annotieren“ enthalten sein. Dadurch sollte die Anwendung mit dem Bild gestartet werden, in dem das Bild annotiert werden kann.

Unterstützung für Maus und Touchpad

Die meisten Anwendungen müssen in der Regel nur drei Ereignisse verarbeiten, bei denen der Bildschirm im Mittelpunkt steht: Rechtsklick, Hover und Drag-and-drop.

Rechtsklick

Alle Aktionen, durch die in einer App ein Kontextmenü angezeigt wird, z. B. das Berühren und Halten eines Listenelements, sollten auch auf Ereignisse mit der rechten Maustaste reagieren. Zur Verarbeitung von Rechtsklickereignissen muss in Apps eine View.OnContextClickListener registriert werden. Weitere Informationen zum Erstellen eines Kontextmenüs finden Sie unter Kontextmenüs erstellen.

Kotlin

yourView.setOnContextClickListener {
  showContextMenu()
  true
}

Java

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

Mauszeiger hierher bewegen

Durch die Verarbeitung von Hover-Ereignissen können Entwickler ihre App-Layouts optimieren und benutzerfreundlicher gestalten. Dies gilt insbesondere für benutzerdefinierte Ansichten. Die beiden häufigsten Beispiele hierfür sind:

  • Sie können Nutzern durch Ändern des Mauszeigersymbols mitteilen, ob ein Element interaktives Verhalten aufweist, z. B. ob es anklickbar oder bearbeitbar ist.
  • Visuelles Feedback zu Elementen in einer großen Liste oder einem Raster hinzufügen, wenn der Mauszeiger darauf bewegt wird

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)
  false // listener did not consume the event.
}

Java

yourView.setOnHoverListener((view, event) -> {
    addVisualHighlighting(true);
    view.setPointerIcon(PointerIcon
            .getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND));
    return true;
});

Drag-and-Drop

In einer Mehrfensterumgebung erwarten Nutzer, dass sie Elemente per Drag-and-drop zwischen Apps verschieben können. Dies gilt sowohl für Computer als auch für Tablets, Smartphones und faltbare Geräte im Split-Screen-Modus.

Entwickler sollten sich überlegen, ob Nutzer Elemente in ihre App ziehen. Beispiele: Fotoeditoren sollten damit rechnen, Fotos zu empfangen, Audioplayer sollten Audiodateien erhalten und Zeichenprogramme sollten Fotos empfangen.

Informationen dazu, wie Sie Drag-and-drop unterstützen, finden Sie in der Android-Dokumentation zu Drag-and-drop und in diesem ChromeOS-Blogpost.

Besondere Hinweise für ChromeOS

  • Denken Sie daran, die Berechtigung über requestDragAndDropPermissions anzufordern, um auf Elemente zuzugreifen, die von außerhalb der App hineingezogen wurden
  • Ein Element muss das Flag View.DRAG_FLAG_GLOBAL haben, um in andere Anwendungen gezogen werden zu können

Erweiterte Zeigerunterstützung

Bei Apps, bei denen eine erweiterte Steuerung der Maus- und Touchpad-Eingabe möglich ist, sollte der Android-Dokumentation für View.onGenericMotionEvent() entsprechen und mit MotionEvent.getSource() zwischen SOURCE_MOUSE und SOURCE_TOUCHSCREEN unterschieden werden.

Sehen Sie sich die MotionEvent an, um das erforderliche Verhalten zu implementieren:

  • Beim Verschieben werden ACTION_HOVER_MOVE-Ereignisse generiert.
  • Schaltflächen generieren ACTION_BUTTON_PRESS- und ACTION_BUTTON_RELEASE-Ereignisse. Du kannst den aktuellen Status aller Maus-/Trackpad-Tasten auch mit getButtonState() prüfen.
  • Beim Scrollen mit dem Mausrad werden ACTION_SCROLL-Ereignisse generiert.

Controller

Einige Android-Geräte mit großem Bildschirm unterstützen bis zu vier Controller. Entwickler sollten zu deren Verarbeitung die standardmäßigen Android-Gamecontroller-APIs verwenden (siehe Unterstützung von Gamecontrollern).

Schaltflächen werden gemeinsamen Werten zugeordnet, die einer gemeinsamen Zuordnung folgen. Leider folgen nicht alle Hersteller von Gamecontrollern dieselben Mapping-Konventionen. Die Nutzerfreundlichkeit lässt sich erheblich verbessern, wenn Nutzer verschiedene beliebte Controllerzuordnungen auswählen können. Weitere Informationen finden Sie unter Gamepad-Tastendrücke verarbeiten.

Eingabeübersetzungsmodus

ChromeOS aktiviert standardmäßig einen Eingabeübersetzungsmodus. Bei den meisten Android-Apps funktioniert dieser Modus wie erwartet in einer Desktopumgebung. Einige Beispiele sind das automatische Aktivieren des Scrollens mit zwei Fingern auf dem Touchpad, das Scrollen mit dem Mausrad und die Zuordnung von unverarbeiteten Anzeigekoordinaten zu Fensterkoordinaten. Im Allgemeinen müssen App-Entwickler keines dieser Verhaltensweisen selbst implementieren.

Wenn eine App ein benutzerdefiniertes Eingabeverhalten implementiert, z. B. die Definition einer benutzerdefinierten Aktion für das Auseinander- und Zusammenziehen auf dem Touchpad, oder wenn 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