Eingabekompatibilität auf großen Bildschirmen

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

  • Grundlegende Tastaturunterstützung testen, z. B. Navigation mit der Tabulatortaste und den Pfeiltasten, der Bestätigung der Texteingabe bei der Eingabe und der Wiedergabe/Pause der Leertaste in Medien-Apps
  • Fügen Sie ggf. Standardtastenkombinationen hinzu, z. B. Strg + Z zum Rückgängigmachen und Strg + S zum Speichern.
  • Grundlegende Mausinteraktionen testen wie durch Rechtsklick für das Kontextmenü, Symboländerungen beim Bewegen des Mauszeigers und Scroll-Ereignisse mit Mausrad oder Touchpad in benutzerdefinierten Ansichten
  • App-spezifische Eingabegeräte testen, z. B. einen Eingabestift zum Zeichnen von Apps, Game-Controller für Spiele und MIDI-Controller für Musik-Apps
  • Erwägen Sie eine erweiterte Eingabeunterstützung, die die App in Desktop-Umgebungen hervorhebt, z. B. Touchpad als Crossfader für DJ-Apps, Mausaufnahme für Spiele und umfangreiche Tastenkombinationen für tastaturorientierte Nutzer.

Tastatur

Die Art und Weise, wie deine App auf Tastatureingaben reagiert, trägt zu einer guten Nutzererfahrung auf dem großen Bildschirm bei. Es gibt drei Arten von Tastatureingaben: Navigation, Tastenanschläge und Tastenkombinationen.

Die Tastaturnavigation wird bei Touch-orientierten Apps selten implementiert, aber Nutzer erwarten sie, wenn sie eine App verwenden und ihre Hände auf einer Tastatur haben. Sie kann auch für Nutzer mit Anforderungen an die Barrierefreiheit auf Smartphones, Tablets, faltbaren Smartphones und Desktop-Geräten unerlässlich sein.

Bei vielen Apps reicht eine einfache Pfeil- und Tab-Navigation aus. Diese wird größtenteils automatisch vom Android-Framework ausgeführt. Beispielsweise ist die 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, was programmatisch oder in XML erfolgen kann (siehe unten). Weitere Informationen finden Sie unter Focus Handling.

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 Navigationskarte für alle fokussierbaren Ansichten basierend auf ihrer Position. Das funktioniert normalerweise wie erwartet und es sind keine weiteren Maßnahmen erforderlich. Wenn die Standardzuordnung für die Anforderungen einer Anwendung 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);

Es empfiehlt sich, vor jedem Release nur über die Tastatur auf alle Funktionen Ihrer App zuzugreifen. Der Zugriff auf die häufigsten Aktionen sollte ohne Maus- oder Toucheingabe einfach sein.

Denken Sie daran, dass die Tastaturunterstützung für Nutzer mit Anforderungen an Bedienungshilfen unerlässlich sein kann.

Tastenanschläge

Bei einer Texteingabe, die über eine Bildschirmtastatur (IME) wie EditText erfolgt, sollten sich Apps auf Geräten mit großen Bildschirmen wie erwartet verhalten, ohne dass der Entwickler zusätzlich etwas tun muss. Bei Tastatureingaben, die vom Framework nicht erwartet werden können, müssen die Apps das Verhalten selbst übernehmen. 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 beenden, und Spiele, die die Bewegung 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 Apps mehrere onKeyDown-Ereignisse verarbeiten müssen, wenn eine Taste gedrückt gehalten oder langsam freigegeben wird. Spiele und Apps, die wissen möchten, wann eine Taste gedrückt wird oder die erwarten, dass Nutzer die Tasten gedrückt halten, können nach dem Ereignis onKeyDown() suchen und die wiederholten onKeyDown-Ereignisse selbst verarbeiten.

Weitere Informationen zur Tastaturunterstützung finden Sie unter Tastaturaktionen verarbeiten.

Verknüpfungen

Bei Verwendung einer Hardwaretastatur werden gängige Tastenkombinationen wie Strg, Alt und Umschalttaste erwartet. Werden sie in einer App nicht implementiert, kann es für die Nutzenden frustrierend sein. Fortgeschrittene Nutzer schätzen Verknüpfungen für häufig verwendete app-spezifische Aufgaben. Verknüpfungen erleichtern die Nutzung einer App und differenzieren 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 einige 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 Schlüsselcode abgefangen. Verwenden Sie KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed(), KeyEvent.isAltPressed() oder KeyEvent.hasModifiers(), um nach einem bestimmten Metaschlüssel zu suchen.

Das Trennen von Tastenkombinationen von anderen Tastenanschlägen (z. B. onKeyUp() und onKeyDown()) kann die Codeverwaltung vereinfachen und ermöglicht die Standardakzeptanz von Metatasten, ohne dass Meta-Tastenprüfungen in jedem Fall manuell implementieren müssen. Das Zulassen aller Meta-Tastenkombinationen kann auch für Nutzer praktischer sein, die mit verschiedenen Tastaturlayouts und Betriebssystemen vertraut sind.

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 Tastenkombinationen in onKeyUp() implementieren, indem Sie wie oben beschrieben nach KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() oder KeyEvent.isAltPressed() suchen. Dies ist einfacher, wenn das Meta-Verhalten eher eine Änderung des App-Verhaltens als eine Verknüpfung darstellt. Beispiel: W bedeutet „vorwärts gehen“ und Umschalttaste + W für „vorwärts 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);
}

Eingabestift

Viele Geräte mit großen Bildschirmen haben einen Eingabestift, der von Android-Apps als Touchscreen-Eingabe genutzt werden kann. Einige Geräte haben möglicherweise auch einen USB- oder Bluetooth-Zeichentisch, z. B. Wacom Intuos. Android-Apps können Bluetooth-Eingaben empfangen, aber nicht über USB.

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

MotionEvent enthält auch zusätzliche Daten:

Historische Punkte

Android fasst Eingabeereignisse in Batches und sendet sie einmal pro Frame. Mit einem Eingabestift können Ereignisse mit viel höheren Frequenzen gemeldet werden als mit dem Display. Beim Erstellen von Zeichenanwendungen ist es wichtig, mithilfe der getHistorical APIs auf Ereignisse in der jüngsten Vergangenheit zu prüfen:

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

Ablehnung von Handflächen

Wenn Nutzer mit einem Eingabestift zeichnen, schreiben oder mit Ihrer App interagieren, berühren sie manchmal den Bildschirm 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 der Handfläche erkennt und ignoriert.

Android bricht Palm Touch-Ereignisse ab, indem ein MotionEvent ausgelöst wird. Wenn Ihre App ACTION_CANCEL empfängt, brechen Sie die Touch-Geste ab. Wenn Ihre Anwendung ACTION_POINTER_UP erhält, prüfen Sie, ob FLAG_CANCELED festgelegt ist. Wenn ja, brechen Sie den Vorgang ab.

Nicht nur für FLAG_CANCELED prüfen. Ab Android 13 legt das System der Einfachheit halber FLAG_CANCELED für ACTION_CANCEL-Ereignisse fest. Bei früheren Versionen ist dies jedoch nicht der Fall.

Android 12

Unter Android 12 (API-Level 32) und niedriger ist die Erkennung der Handballenablehnung nur bei Single-Pointer-Touch-Ereignissen möglich. Wenn eine Handfläche der einzige Zeiger ist, bricht das System das Ereignis ab, indem ACTION_CANCEL für das Bewegungsereignisobjekt festgelegt wird. Wenn andere Zeiger gedrückt sind, legt das System ACTION_POINTER_UP fest. Dies ist nicht ausreichend, um die Palmenablehnung zu erkennen.

Android 13

Wenn unter Android 13 (API-Level 33) und höher eine Handfläche der einzige Zeiger ist, bricht das System das Ereignis ab, indem ACTION_CANCEL und FLAG_CANCELED für das Bewegungsereignisobjekt festgelegt werden. Wenn andere Zeiger gedrückt sind, legt das System ACTION_POINTER_UP und FLAG_CANCELED fest.

Immer wenn deine App ein Bewegungsereignis mit ACTION_POINTER_UP empfängt, wird nach FLAG_CANCELED gesucht, um festzustellen, ob das Ereignis auf eine Ablehnung der Handfläche oder eine andere Ereignisabmeldung hinweist.

Notizen-Apps

ChromeOS hat einen speziellen Intent, der Nutzern registrierte Notizen-Apps anzeigt. 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-App zum Erstellen von Notizen auswählen. Wenn eine neue Notiz angefordert wird, sollte die App eine leere Notiz erstellen, die mit dem Eingabestift eingegeben werden kann. Wenn der Nutzer ein Bild (z. B. einen Screenshot oder ein heruntergeladenes Bild) mit Anmerkungen versehen möchte, wird die Anwendung mit ClipData gestartet, das ein oder mehrere Elemente mit content://-URIs enthält. Die App sollte eine Notiz erstellen, die das erste angehängte Bild als Hintergrundbild verwendet, und einen Modus aktivieren, in dem der Nutzer mit einem Eingabestift auf dem Bildschirm zeichnen kann.

Notizen-Intents ohne Eingabestift testen

Um zu testen, ob eine App ohne aktiven Eingabestift korrekt auf Intents zum Erstellen von Notizen reagiert, verwenden Sie die folgende Methode, um die Optionen für Notizen unter ChromeOS aufzurufen:

  1. In den Entwicklermodus wechseln und 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 am Ende der Datei --ash-enable-palette in eine neue Zeile einzufügen.
  5. Speichern Sie, indem Sie die Esc-Taste drücken, dann :, w, q eingeben und die Eingabetaste drücken
  6. Drücke Strg + Alt + F1, um zur regulären ChromeOS-Benutzeroberfläche zurückzukehren
  7. Abmelden und wieder anmelden

In der Ablage sollte jetzt ein Eingabestiftmenü zu sehen sein:

  • Tippen Sie in der Ablage auf die Schaltfläche für den Eingabestift und wählen Sie Neue Notiz aus. Daraufhin sollte eine leere Zeichnungsnotiz geöffnet werden.
  • Machen Sie einen Screenshot. Wählen Sie in der Ablage Eingabestift-Schaltfläche > Bildschirmaufnahme aus oder laden Sie ein Bild herunter. In der Benachrichtigung sollte die Option „Bild annotieren“ verfügbar sein. Dadurch sollte die Anwendung gestartet werden. Das Bild sollte nun mit Anmerkungen versehen werden.

Unterstützung für Maus und Touchpad

Die meisten Anwendungen müssen in der Regel nur drei große Bildschirmereignisse verarbeiten: Rechtsklick, Hover und Drag-and-drop.

Rechtsklick

Alle Aktionen, die dazu führen, dass eine App ein Kontextmenü anzeigt, z. B. das Berühren und Halten eines Listeneintrags, sollte auch auf einen Rechtsklick reagieren. Für die Verarbeitung von Klickereignissen sollten Apps ein View.OnContextClickListener registrieren. 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;
});

Hover

Entwickler können ihre App-Layouts ansprechender und nutzerfreundlicher gestalten, indem sie Hover-Ereignisse verarbeiten. Dies gilt insbesondere für benutzerdefinierte Ansichten. Die beiden häufigsten Beispiele hierfür sind:

  • Nutzer erkennen, ob ein Element interaktiv ist, z. B. anklickbar oder bearbeitbar ist, indem das Mauszeigersymbol geändert wird.
  • Das Hinzufügen von visuellem Feedback zu Elementen in einer großen Liste oder einem Raster, wenn der Zeiger darauf

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 Umgebung mit Mehrfenstermodus erwarten Nutzer, Elemente per Drag-and-drop zwischen Apps verschieben zu können. Das gilt sowohl für Computer als auch für Tablets, Smartphones und faltbare Smartphones im geteilten Bildschirmmodus.

Entwickler sollten überlegen, ob Nutzer wahrscheinlich Elemente in ihre App ziehen werden. Hier einige gängige Beispiele: Fotoeditoren sollten damit rechnen, dass Fotos empfangen werden, Audioplayer erhalten Audiodateien und Zeichenprogramme erhalten Fotos.

Informationen dazu, wie Sie Drag-and-drop unterstützen können, finden Sie in der Drag-and-drop-Dokumentation für Android und in diesem ChromeOS-Blogpost.

Besondere Hinweise für ChromeOS

  • Fordern Sie über requestDragAndDropPermissions die Berechtigung an, auf Elemente zuzugreifen, die von außerhalb der App
  • Ein Element muss das Flag View.DRAG_FLAG_GLOBAL haben, damit es in andere Anwendungen verschoben werden kann.

Erweiterte Unterstützung für Zeiger

Apps, die eine erweiterte Eingabe per Maus und Touchpad ausführen, sollten der Android-Dokumentation für View.onGenericMotionEvent() folgen und MotionEvent.getSource() verwenden, um zwischen SOURCE_MOUSE und SOURCE_TOUCHSCREEN zu unterscheiden.

Untersuchen Sie MotionEvent, um das erforderliche Verhalten zu implementieren:

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

Gamecontroller

Einige Android-Geräte mit großem Bildschirm unterstützen bis zu vier Gamecontroller. Entwickler sollten für deren Verarbeitung die standardmäßigen Android-Gamecontroller APIs verwenden. Weitere Informationen finden Sie unter Unterstützung von Gamecontrollern.

Schaltflächen werden allgemeinen Werten gemäß einer gemeinsamen Zuordnung zugeordnet. Leider folgen nicht alle Controller-Hersteller den gleichen Kartenkonventionen. Sie können die Nutzerfreundlichkeit deutlich verbessern, wenn Sie Nutzern die Möglichkeit geben, verschiedene beliebte Controller-Zuordnungen auszuwählen. Weitere Informationen finden Sie unter Drücken von Gamepad-Tasten verarbeiten.

Übersetzungsmodus eingeben

In ChromeOS ist der Modus für die Eingabeübersetzung standardmäßig aktiviert. Bei den meisten Android-Apps funktioniert dieser Modus wie erwartet in einer Desktopumgebung. Dazu gehören beispielsweise das automatische Aktivieren des Scrollens mit zwei Fingern auf dem Touchpad, das Scrollen mit dem Mausrad und das Zuordnen von Rohkoordinaten der Anzeige zu Fensterkoordinaten. Im Allgemeinen müssen App-Entwickler keines dieser Verhaltensweisen selbst implementieren.

Wenn eine App benutzerdefiniertes Eingabeverhalten implementiert, z. B. das Definieren einer benutzerdefinierten Auseinander-/Zusammenziehen-Aktion des zwei Fingern auf dem Touchpad, oder wenn diese Eingabeübersetzungen nicht die von der App erwarteten Eingabeereignisse liefert, 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" />

Weitere Informationen