Apps entwickeln

Das folgende Material richtet sich an App-Entwickler.

Damit Ihre App die Drehung unterstützt, MÜSSEN Sie Folgendes tun:

  1. Fügen Sie ein FocusParkingView in das entsprechende Aktivitätslayout ein.
  2. Stellen Sie sicher, dass die Ansichten fokussierbar oder nicht fokussierbar sind.
  3. Mit FocusAreas können Sie alle fokussierbaren Ansichten mit Ausnahme der FocusParkingView.

Jede dieser Aufgaben wird im Folgenden beschrieben, nachdem Sie Ihre Umgebung eingerichtet haben, Anwendungen mit Drehbewegung entwickeln.

Drehregler einrichten

Bevor Sie mit der Entwicklung drehbarer Apps beginnen können, benötigen Sie entweder einen Drehregler oder ein Stand-in. Ihnen stehen die unten beschriebenen Optionen zur Verfügung.

Emulator

source build/envsetup.sh && lunch car_x86_64-userdebug
m -j
emulator -wipe-data -no-snapshot -writable-system

Sie können auch aosp_car_x86_64-userdebug verwenden.

So greifen Sie auf den emulierten Drehregler zu:

  1. Tippe unten in der Symbolleiste auf das Dreipunkt-Menü:

    <ph type="x-smartling-placeholder">
    </ph> Auf emulierten Drehregler zugreifen
    Abbildung 1. Auf emulierten Drehregler zugreifen
  2. Wähle im Fenster mit den erweiterten Steuerelementen Drehrad aus:

    <ph type="x-smartling-placeholder">
    </ph> Drehknopf auswählen
    Abbildung 2: Wähle das Drehknopf aus.

USB-Tastatur

  • Schließen Sie eine USB-Tastatur an Ihr Gerät mit Android Automotive OS (AAOS) an. In einigen Fällen wird die Bildschirmtastatur nicht angezeigt.
  • Verwenden Sie einen userdebug- oder eng-Build.
  • Schlüsselereignisfilter aktivieren:
    adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
    
  • In der folgenden Tabelle finden Sie den entsprechenden Schlüssel für die einzelnen Aktionen:
    Schlüssel Drehaktion
    F Gegen den Uhrzeigersinn drehen
    E Im Uhrzeigersinn drehen
    A Präzisionsausrichtung links
    D Präzisionsausrichtung rechts
    W Präzisionsausrichtung oben
    S Präzisionsausrichtung unten
    F oder Komma Schaltfläche in der Mitte
    R oder Esc Schaltfläche „Zurück“

ADB-Befehle

Sie können car_service-Befehle verwenden, um Ereignisse für die Dreheingabe einzuschleusen. Diese Befehle können auf Geräten mit Android Automotive OS (AAOS) oder in einem Emulator ausgeführt werden.

„car_service“-Befehle Drehknopf
adb shell cmd car_service inject-rotary Gegen den Uhrzeigersinn drehen
adb shell cmd car_service inject-rotary -c true Im Uhrzeigersinn drehen
adb shell cmd car_service inject-rotary -dt 100 50 Mehrmals gegen den Uhrzeigersinn drehen (vor 100 ms und vor 50 ms)
adb shell cmd car_service inject-key 282 Präzisionsausrichtung links
adb shell cmd car_service inject-key 283 Präzisionsausrichtung rechts
adb shell cmd car_service inject-key 280 Präzisionsausrichtung oben
adb shell cmd car_service inject-key 281 Präzisionsausrichtung unten
adb shell cmd car_service inject-key 23 Klick in der Mitte
adb shell input keyevent inject-key 4 Klick auf Schaltfläche „Zurück“

OEM-Drehsteuerung

Wenn die Hardware des Drehreglers einsatzbereit ist, ist dies die höchste eine realistische Option wählen. Dies ist besonders nützlich, um die schnelle Rotation zu testen.

FokusParkenAusblick

FocusParkingView ist eine transparente Ansicht im Car UI Library (car-ui-library). RotaryService verwendet ihn, um die Navigation über den Drehknopf zu unterstützen. FocusParkingView muss die erste fokussierbare Ansicht sein im Layout. Es muss außerhalb aller FocusArea platziert werden. Jedes Fenster muss eine FocusParkingView Wenn Sie bereits das Basislayout „car-ui-library“ verwenden, die ein FocusParkingView enthält, müssen Sie keine weitere hinzufügen FocusParkingView Unten sehen Sie ein Beispiel für FocusParkingView in RotaryPlayground.

<FrameLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <com.android.car.ui.FocusParkingView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
   <FrameLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
</FrameLayout>

Im Folgenden finden Sie einige Gründe, warum Sie einen FocusParkingView benötigen:

  1. Android entfernt den Fokus nicht automatisch, wenn der Fokus in einem anderen Fenster liegt. Wenn Sie wenn Sie versuchen, den Fokus im vorherigen Fenster zu fokussieren, stellt Android eine Ansicht in diesem Fenster neu fokussiert führt dazu, dass zwei Fenster gleichzeitig im Fokus sind. FocusParkingView hinzufügen können Sie dieses Problem beheben. Diese Ansicht ist transparent und der standardmäßige Fokus wird hervorgehoben. ist deaktiviert, sodass es für den Nutzer unsichtbar ist, egal ob im Fokus oder nicht. Die Kamera kann den Fokus erhalten, sodass RotaryService den Fokus darauf parken kann. , um die Hervorhebung zu entfernen.
  2. Wenn sich nur ein FocusArea im aktuellen Fenster befindet, drehen Sie den Controller im Feld FocusArea führt dazu, dass RotaryService den Fokus verschiebt von der rechten zur linken (und umgekehrt) zu wechseln. Diese Ansicht hinzufügen in jedem Fenster das Problem beheben. Wenn RotaryService den Fokus bestimmt FocusParkingView ist, kann er feststellen, an diesem Punkt erscheinen, da der Fokus nicht bewegt wird.
  3. Wenn über den Drehknopf eine App gestartet wird, fokussiert Android die erste fokussierbare Ansicht. Dieser ist immer FocusParkingView. Das FocusParkingView ermittelt die optimale Ansicht und wendet dann den Fokus an.

Fokussierbare Ansichten

RotaryService baut auf dem Android-Framework auf bestehend Konzept der Perspektive, da Smartphones noch mit physischen Tastaturen und Steuerkreuzen ausgestattet waren. Das vorhandene Attribut android:nextFocusForward wird für den Drehschalter umfunktioniert (siehe FocusArea-Anpassung), aber android:nextFocusLeft, android:nextFocusRight android:nextFocusUp und android:nextFocusDown nicht.

RotaryService konzentriert sich nur auf Aufrufe, die fokussierbar sind. Einige Ansichten, wie Buttons, in der Regel fokussierbar sind. Andere, z. B. TextViews und ViewGroups, normalerweise nicht. Anklickbare Ansichten sind automatisch fokussierbar, Aufrufe automatisch anklickbar, wenn sie einen Klick-Listener haben. Wenn diese automatische Logik zum gewünschten Ergebnis führt, müssen Sie die Fokussierbarkeit der Ansicht nicht explizit festlegen. Wenn bei der automatischen Logik keine gewünschte Fokussierbarkeit ergibt, setzen Sie das Attribut android:focusable auf true oder false auswählen oder die Fokussierbarkeit der Ansicht programmatisch festlegen mit View.setFocusable(boolean). Damit RotaryService den Fokus darauf legen kann, MUSS eine Ansicht MÜSSEN die folgenden Anforderungen erfüllen:

  • Fokussierbar
  • Aktiviert
  • Sichtbar
  • Werte ungleich null für Breite und Höhe haben

Wenn eine Ansicht nicht alle diese Anforderungen erfüllt, z. B. bei einer fokussierbaren, aber deaktivierten Schaltfläche, kann der Nutzer nicht mit dem Drehknopf darauf fokussieren. Wenn Sie den Schwerpunkt auf deaktivierte Datenansichten legen möchten, können Sie statt android:state_enabled einen benutzerdefinierten Status verwenden, um zu steuern, die Ansicht erscheint, ohne anzugeben, dass Android die App als deaktiviert ansehen soll. Deine App kann Informationen liefern der Nutzer, warum die Ansicht nach dem Antippen deaktiviert wird. Im nächsten Abschnitt wird dies beschrieben.

Benutzerdefinierter Status

So fügen Sie einen benutzerdefinierten Status hinzu:

  1. So fügen Sie ein benutzerdefiniertes Attribut hinzu: zu Ihrer Ansicht hinzufügen. Wenn Sie beispielsweise dem benutzerdefinierten Status state_rotary_enabled Ansichtsklasse CustomView, verwenden:
    <declare-styleable name="CustomView">
        <attr name="state_rotary_enabled" format="boolean" />
    </declare-styleable>
    
  2. Um diesen Status zu verfolgen, fügen Sie Ihrer Ansicht eine Instanzvariable zusammen mit Zugriffsmethoden hinzu:
    private boolean mRotaryEnabled;
    public boolean getRotaryEnabled() { return mRotaryEnabled; }
    public void setRotaryEnabled(boolean rotaryEnabled) {
        mRotaryEnabled = rotaryEnabled;
    }
    
  3. So lesen Sie den Wert Ihres Attributs beim Erstellen Ihrer Ansicht:
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
    mRotaryEnabled = a.getBoolean(R.styleable.CustomView_state_rotary_enabled);
    
  4. Überschreiben Sie in Ihrer Ansichtsklasse die Methode onCreateDrawableState() und fügen Sie gegebenenfalls den benutzerdefinierten Status hinzu. Hier einige Beispiele:
    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        if (mRotaryEnabled) extraSpace++;
        int[] drawableState = super.onCreateDrawableState(extraSpace);
        if (mRotaryEnabled) {
            mergeDrawableStates(drawableState, { R.attr.state_rotary_enabled });
        }
        return drawableState;
    }
    
  5. Passen Sie die Leistung des Klick-Handlers Ihrer Ansicht je nach Status an. Beispiel: Der Parameter Der Klick-Handler reagiert möglicherweise gar nicht oder erscheint einen Pop-up, wenn mRotaryEnabled ist false.
  6. Damit die Schaltfläche deaktiviert erscheint, verwenden Sie im Hintergrund-Drawable der Ansicht Folgendes: app:state_rotary_enabled statt android:state_enabled. Fügen Sie Folgendes hinzu, falls noch nicht geschehen:
    xmlns:app="http://schemas.android.com/apk/res-auto"
    
  7. Wenn die Ansicht in einem Layout deaktiviert ist, ersetzen Sie android:enabled="false" durch app:state_rotary_enabled="false" und fügen Sie dann den Namespace app hinzu. wie oben beschrieben.
  8. Wenn Ihre Ansicht programmatisch deaktiviert ist, ersetzen Sie Aufrufe von setEnabled() mit Aufrufen von setRotaryEnabled().

Fokusbereich

Mit FocusAreas können Sie die fokussierbaren Ansichten in Blöcke unterteilen, um die Navigation zu erleichtern einfacher zu machen und mit anderen Apps konsistent zu sein. Verfügt Ihre App beispielsweise über eine Symbolleiste, sollte sich in einer separaten FocusArea vom Rest deiner App befinden. Tableisten und Andere Navigationselemente sollten auch vom Rest der App getrennt sein. Große Listen sollte im Allgemeinen ein eigenes FocusArea haben. Andernfalls müssen Nutzer um auf einige Ansichten zuzugreifen.

FocusArea ist eine abgeleitete Klasse von LinearLayout in der „car-ui-library“. Wenn diese Funktion aktiviert ist, zeichnet FocusArea eine Markierung, wenn eine seiner der Nachfolgerelemente fokussiert ist. Weitere Informationen finden Sie unter Markierungsanpassung hervorheben:

Wenn Sie beim Erstellen eines Navigationsblocks in der Layoutdatei einen LinearLayout als Container für diesen Block; verwenden Sie stattdessen FocusArea. Andernfalls umschließen Sie den Block in einem FocusArea.

Verschachtele eine FocusArea NICHT in einer anderen FocusArea. Dies führt zu nicht definiertem Navigationsverhalten. Alle fokussierbaren Ansichten müssen in FocusArea verschachtelt.

Ein Beispiel für ein FocusArea in RotaryPlayground wird unten angezeigt:

<com.android.car.ui.FocusArea
       android:layout_margin="16dp"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical">
       <EditText
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:singleLine="true">
       </EditText>
   </com.android.car.ui.FocusArea>

FocusArea funktioniert so:

  1. Bei der Verarbeitung von Dreh- und Anstupseraktionen sucht RotaryService nach Instanzen von FocusArea in der Ansichtshierarchie.
  2. Beim Empfang eines Rotationsereignisses verschiebt RotaryService den Fokus auf ein anderes Ansicht, die im selben FocusArea hervorgehoben werden kann.
  3. Beim Empfangen eines Anstupser-Ereignisses verschiebt RotaryService den Fokus in eine andere Ansicht die in einer anderen (normalerweise nebeneinanderliegenden) FocusArea hervorgehoben werden können.

Wenn Sie kein FocusAreas in Ihr Layout einfügen, wird die Stammansicht impliziten Fokusbereich. Der Nutzer kann die App nicht bewegen. Stattdessen werden sie durch alle fokussierbaren Ansichten drehen, was für Dialoge geeignet sein kann.

FocusArea-Anpassung

Zur Anpassung der Drehsteuerung können zwei Standardattribute für die Ansicht verwendet werden:

  • Mit android:nextFocusForward können App-Entwickler die Rotation angeben im Fokusbereich anzuordnen. Dies ist dasselbe Attribut, das zur Steuerung der TAB-Reihenfolge für Tastaturnavigation verwenden. Verwenden Sie dieses Attribut NICHT, um eine Schleife zu erstellen. Verwenden Sie stattdessen app:wrapAround (siehe unten), um eine Schleife zu erstellen.
  • Mit android:focusedByDefault können App-Entwickler die Standardfokusansicht im Fenster. Verwenden Sie NICHT dieses Attribut und app:defaultFocus (siehe unten) im selben FocusArea.

FocusArea definiert auch einige Attribute zum Anpassen der Drehsteuerung. Implizite Fokusbereiche können mit diesen Attributen nicht angepasst werden.

  1. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocus kann verwendet werden, um gibt die ID einer fokussierbaren Nachfolgeransicht an, auf die der Fokus liegen sollte, wenn der Nutzer wird an diese/n FocusArea weitergeleitet.
  2. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocusOverridesHistory kann auf true gesetzt werden, damit die oben angegebene Ansicht fokussiert wird, auch wenn angezeigt, die auf eine andere Ansicht in dieser FocusArea fokussiert waren.
  3. (Android 12)
    Verwenden Sie app:nudgeLeftShortcut, app:nudgeRightShortcut, app:nudgeUpShortcut und app:nudgeDownShortcut zur Angabe der ID einer fokussierbaren Nachfolgeransicht, auf die der Fokus gesetzt werden sollte, wenn der die der Nutzer in eine bestimmte Richtung bewegt. Weitere Informationen finden Sie in den Tastenkombinationen für Erinnerungen unten.

    (Android 11 QPR3, Android 11 Car, in Android 12 eingestellt) app:nudgeShortcut und app:nudgeShortcutDirection unterstützte nur eine Anstups-Tastenkombination.

  4. (Android 11 QPR3, Android 11 Car, Android 12)
    Um die Rotation in dieser FocusArea zu aktivieren, app:wrapAround kann auf true festgelegt werden. Dies wird vor allem verwendet, wenn Ansichten so angeordnet sind, Kreis oder Oval.
  5. (Android 11 QPR3, Android 11 Car, Android 12)
    Um den Abstand der Markierung in diese FocusArea, app:highlightPaddingStart verwenden, app:highlightPaddingEnd, app:highlightPaddingTop app:highlightPaddingBottom, app:highlightPaddingHorizontal, und app:highlightPaddingVertical.
  6. (Android 11 QPR3, Android 11 Car, Android 12)
    So passt du die wahrgenommenen Grenzen von FocusArea an, um ein Anstupser-Ziel zu finden: Verwenden Sie app:startBoundOffset, app:endBoundOffset, app:topBoundOffset, app:bottomBoundOffset app:horizontalBoundOffset und app:verticalBoundOffset.
  7. (Android 11 QPR3, Android 11 Car, Android 12)
    Um die ID eines Objekts explizit anzugeben, neben FocusArea (oder Bereichen) in der angegebenen Richtung, verwenden Sie app:nudgeLeft, app:nudgeRight, app:nudgeUp und app:nudgeDown Verwenden Sie diese Option, wenn die standardmäßig verwendete geometrische Suche das gewünschte Ziel nicht findet.

Mit Nudging wird in der Regel zwischen FocusAreas (Fokusbereichen) gewechselt. Aber mit den Anstupser-Tastenkombinationen Mit „Anstoßen“ wird manchmal zuerst innerhalb eines FocusArea-Elements gewechselt, sodass der Nutzer , um zweimal daran zu springen, um zur nächsten FocusArea zu gelangen. Tastenkombinationen für Anstupser sind hilfreich wenn FocusArea eine lange Liste enthält, gefolgt von einem Unverankerte Aktionsschaltfläche wie im Beispiel unten:

<ph type="x-smartling-placeholder">
</ph> Kurzbefehl zum Anstreichen
Abbildung 3: Kurzbefehl zum Anstoßen

Ohne die Funktion „Anstoßen“ müssten Nutzer durch die gesamte Liste blättern, um der FAB.

Hervorhebungsanpassung hervorheben

Wie bereits erwähnt, baut RotaryService auf dem bestehenden Konzept des Android-Frameworks auf: Fokus anzeigen. Beim Drehen und Anstupsen verschiebt RotaryService den Fokus eine Ansicht zu fokussieren und eine andere wieder zu fokussieren. Wenn in Android eine Ansicht im Fokus ist und die Ansicht:

  • Hat eine eigene Fokushervorhebung angegeben, zeichnet Android diese.
  • Es wird keine Fokushervorhebung angegeben und die Standardeinstellung ist nicht deaktiviert, Android zeichnet die standardmäßige Fokushervorhebung für die Ansicht.

In Apps, die für Touch-Gesten entwickelt wurden, wird normalerweise nicht die entsprechenden Hervorhebungen angegeben.

Die standardmäßige Fokushervorhebung wird vom Android-Framework bereitgestellt und kann überschrieben werden durch den OEM. App-Entwickler erhalten diese Informationen, wenn ihr Design auf Theme.DeviceDefault

Verwenden Sie für eine einheitliche Nutzererfahrung nach Möglichkeit die standardmäßige Fokushervorhebung. Wenn Sie eine benutzerdefinierte Markierung (z. B. rund oder pillenförmig) oder mit einem Design, das nicht von Theme.DeviceDefault abgeleitet ist, verwenden Sie die Auto-UI-Bibliothek Ressourcen, um eine eigene Fokushervorhebung für jede Ansicht festzulegen.

Wenn du eine benutzerdefinierte Fokushervorhebung für eine Ansicht festlegen möchtest, ändere das Drawable für den Hintergrund oder den Vordergrund der Ansicht in ein Drawable, das sich unterscheidet, wenn die Ansicht fokussiert ist. In der Regel ändern Sie im Hintergrund. Das folgende Drawable, wenn es als Hintergrund für eine quadratische Ansicht verwendet wird, erzeugt eine runde Hervorhebung:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_focused="true" android:state_pressed="true">
      <shape android:shape="oval">
         <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
         <stroke
            android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
            android:color="@color/car_ui_rotary_focus_pressed_stroke_color"/>
      </shape>
   </item>
   <item android:state_focused="true">
      <shape android:shape="oval">
         <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
         <stroke
            android:width="@dimen/car_ui_rotary_focus_stroke_width"
            android:color="@color/car_ui_rotary_focus_stroke_color"/>
      </shape>
   </item>
   <item>
      <ripple...>
         ...
      </ripple>
   </item>
</selector>

(Android 11 QPR3, Android 11 Car, Android 12) Fett-Ressourcenreferenzen im Beispiel die von der car-ui-library definierten Ressourcen an. Der OEM überschreibt diese, um einheitlich zu sein. mit der vorgegebenen Hervorhebung. Dadurch wird sichergestellt, dass die Farbe, Strichbreite usw. ändern sich nicht, wenn Nutzende zwischen Ansichten mit benutzerdefiniertem Fokus wechseln. Hervorhebung und eine Ansicht mit der Standardeinstellung „Fokus hervorheben“. Das letzte Element ist eine Welle für die Berührung. Die Standardwerte für die fett gedruckten Ressourcen werden wie folgt angezeigt:

<ph type="x-smartling-placeholder">
</ph> Standardwerte für Ressourcen in Fettdruck
Abbildung 4: Standardwerte für fett gedruckte Ressourcen

Außerdem wird eine benutzerdefinierte Fokushervorhebung angefordert, wenn eine Schaltfläche durchgehend Hintergrundfarbe, um die Nutzenden darauf aufmerksam zu machen, wie im Beispiel unten. Dies kann dazu führen, Hervorhebung schwer zu sehen ist. In diesem Fall können Sie mit sekundäre Farben:

Einfarbige Hintergrundfarbe
  • (Android 11 QPR3, Android 11 Car, Android 12)
    car_ui_rotary_focus_fill_secondary_color
    car_ui_rotary_focus_stroke_secondary_color
  • (Android 12)
    car_ui_rotary_focus_pressed_fill_secondary_color
    car_ui_rotary_focus_pressed_stroke_secondary_color

Beispiel:

Fokussiert, nicht gedrückt Fokussiert, gedrückt
Fokussiert, nicht gedrückt Fokussiert, gedrückt

Drehbares Scrollen

Wenn deine App RecyclerViews verwendet, SOLLTEN du Folgendes verwenden: CarUiRecyclerView. Dadurch wird sichergestellt, dass Ihre UI da die Anpassungen eines OEMs für alle CarUiRecyclerViews gelten.

Wenn alle Elemente in Ihrer Liste fokussierbar sind, müssen Sie nichts weiter tun. Mit einem Drehknopf bewegt sich der Fokus durch die Elemente in der Liste und die Liste wird gescrollt um das neu fokussierte Element sichtbar zu machen.

(Android 11 QPR3, Android 11 Car, Android 12)
Bei einer Mischung aus fokussierbaren und nicht fokussierbaren oder wenn alle Elemente nicht fokussierbar sind, können Sie das Scrollen aktivieren. Nutzende mithilfe des Drehreglers schrittweise durch die Liste scrollen, ohne sie zu überspringen. nicht fokussierbaren Elementen. Um das Scrollen durch Drehbewegungen zu aktivieren, legen Sie den app:rotaryScrollEnabled fest. auf true setzen.

(Android 11 QPR3, Android 11 Car, Android 12)
Sie können das Scrollen durch Drehbewegungen einschließlich AVCarUiRecyclerView, mit der Funktion setRotaryScrollEnabled()-Methode in CarUiUtils. In diesem Fall sind folgende Schritte erforderlich:

  • Machen Sie die scrollbare Ansicht fokussierbar, damit sie im Fokus ist, wenn keine fokussierbare untergeordnete Ansichten sichtbar sind.
  • Deaktivieren Sie die standardmäßige Fokushervorhebung in der scrollbaren Ansicht, indem Sie setDefaultFocusHighlightEnabled(false), damit die scrollbare Ansicht nicht fokussiert ist,
  • Stellen Sie sicher, dass die scrollbare Ansicht vor den untergeordneten Elementen im Fokus ist, indem Sie setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
  • Mit SOURCE_ROTARY_ENCODER auf MotionEvents warten und entweder AXIS_VSCROLL oder AXIS_HSCROLL, um die zu scrollende Entfernung und die (durch das Schild).

Wenn drehbares Scrollen auf einem CarUiRecyclerView aktiviert ist und der Nutzer zu einem Bereich, in dem keine fokussierbaren Ansichten vorhanden sind, ändert sich die Bildlaufleiste von Grau zu Blau, als um anzuzeigen, dass die Bildlaufleiste fokussiert ist. Sie können einen ähnlichen Effekt implementieren.

Die MotionEvents sind dieselben, wie sie mit einem Mausrad generiert werden, mit Ausnahme der Quelle.

Direktbearbeitungsmodus

Normalerweise wird durch Anstupsen und Drehen durch die Benutzeroberfläche navigiert, während die Taste in der Mitte gedrückt wird. auch wenn das nicht immer der Fall ist. Wenn eine nutzende Person beispielsweise die Weckerlautstärke einstellen möchten, können sie mit dem Drehregler zum Lautstärkeregler navigieren, Taste in der Mitte, drehe den Controller, um die Weckerlautstärke anzupassen, und drücke dann die Zurück-Taste um zur Navigation zurückzukehren. Dies wird als direkte Bearbeitung (DM) bezeichnet. In dieser Modus verwendet wird, dient der Drehregler zur direkten Interaktion mit der Ansicht, nicht zur Navigation.

Es gibt zwei Möglichkeiten, DMs zu implementieren. Wenn Sie nur die Drehung und die gewünschte Ansicht zum Manipulieren, reagiert auf ACTION_SCROLL_FORWARD und ACTION_SCROLL_BACKWARD AccessibilityEventen entsprechend an, verwenden Sie die einfachen Mechanismus. Verwenden Sie andernfalls die Option Erweitert.

Der einfache Mechanismus ist die einzige Option in Systemfenstern. Apps können beide Mechanismen verwenden.

Einfacher Mechanismus

(Android 11 QPR3, Android 11 Car, Android 12)
Ihre App sollte folgende Aktionen ausführen: DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable). RotaryService erkennt, wenn sich der Nutzer im DM-Modus befindet, und wechselt in diesen Modus, wenn der Nutzer drückt die Taste in der Mitte, während eine Ansicht fokussiert ist. Im DM-Modus werden Rotationen ACTION_SCROLL_FORWARD oder ACTION_SCROLL_BACKWARD und beendet den DM-Modus wenn der Nutzer auf die Schaltfläche „Zurück“ drückt. Mit dem einfachen Mechanismus wird der ausgewählte Status beim Starten und Beenden des DM-Modus die Ansicht ändern.

Um einen visuellen Hinweis darauf zu geben, dass sich der Nutzer im DM-Modus befindet, ändern Sie Ihre Ansicht wenn diese Option ausgewählt ist. So können Sie zum Beispiel den Hintergrund ändern, android:state_selected ist true.

Erweiterter Mechanismus

Die App bestimmt, wann RotaryService in den DM-Modus wechselt und ihn beendet. Für eine einheitliche Wenn eine DM-Ansicht aktiviert ist, sollte durch Drücken der mittleren Schaltfläche in den DM-Modus gewechselt werden. und die Schaltfläche „Zurück“ sollte den DM-Modus beenden. Wenn Sie die mittlere Taste und/oder die Erinnerungsfunktion nicht verwenden, können sie eine alternative Möglichkeit sein, den DM-Modus zu beenden. Für Apps wie Maps: Eine Schaltfläche zur Darstellung Eine DN kann verwendet werden, um in den DM-Modus zu wechseln.

Zur Unterstützung des erweiterten Modus für Direktnachrichten muss eine Ansicht:

  1. (Android 11 QPR3, Android 11 Car, Android 12) MUSS auf KEYCODE_DPAD_CENTER warten. um in den DM-Modus zu wechseln und auf ein KEYCODE_BACK-Ereignis zu warten, um den DM-Modus zu beenden, in jedem Fall DirectManipulationHelper.enableDirectManipulationMode() aufrufen. Führen Sie einen der folgenden Schritte aus, um auf diese Ereignisse zu warten: <ph type="x-smartling-placeholder">
      </ph>
    • Registriere ein OnKeyListener.
    • oder
    • Erweitern Sie die Ansicht und überschreiben Sie dann die dispatchKeyEvent()-Methode.
  2. SOLLTE auf Anstupser-Ereignisse achten (KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT oder KEYCODE_DPAD_RIGHT), wenn die Ansicht „Anstupser“ verwenden.
  3. MÜSSEN auf MotionEvent s achten und die Anzahl der Drehungen in AXIS_SCROLL abrufen wenn die Ansicht die Rotation übernehmen möchte. Dafür gibt es mehrere Möglichkeiten: <ph type="x-smartling-placeholder">
      </ph>
    1. Registriere ein OnGenericMotionListener.
    2. Erweitern Sie die Ansicht und überschreiben Sie die zugehörige dispatchTouchEvent()-Methode.
  4. Damit Sie nicht im DM-Modus hängen bleiben, MÜSSEN Sie den DM-Modus beenden, wenn das Fragment oder die Aktivität die Ansicht verlassen. ist nicht interaktiv.
  5. SOLLTEN Sie einen visuellen Hinweis bereitstellen, dass sich die Ansicht im DM-Modus befindet.

Im Folgenden finden Sie ein Beispiel für eine benutzerdefinierte Ansicht, in der der DM-Modus zum Schwenken und Zoomen einer Karte verwendet wird:

/** Whether this view is in DM mode. */
private boolean mInDirectManipulationMode;

/** Initializes the view. Called by the constructors. */ private void init() { setOnKeyListener((view, keyCode, keyEvent) -> { boolean isActionUp = keyEvent.getAction() == KeyEvent.ACTION_UP; switch (keyCode) { // Always consume KEYCODE_DPAD_CENTER and KEYCODE_BACK events. case KeyEvent.KEYCODE_DPAD_CENTER: if (!mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = true; DirectManipulationHelper.enableDirectManipulationMode(this, true); setSelected(true); // visually indicate DM mode } return true; case KeyEvent.KEYCODE_BACK: if (mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); setSelected(false); } return true; // Consume controller nudge events only when in DM mode. // When in DM mode, nudges pan the map. case KeyEvent.KEYCODE_DPAD_UP: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, -10f); return true; case KeyEvent.KEYCODE_DPAD_DOWN: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, 10f); return true; case KeyEvent.KEYCODE_DPAD_LEFT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(-10f, 0f); return true; case KeyEvent.KEYCODE_DPAD_RIGHT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(10f, 0f); return true; // Don't consume other key events. default: return false; } });
// When in DM mode, rotation zooms the map. setOnGenericMotionListener(((view, motionEvent) -> { if (!mInDirectManipulationMode) return false; float scroll = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL); zoom(10 * scroll); return true; })); }
@Override public void onPause() { if (mInDirectManipulationMode) { // To ensure that the user doesn't get stuck in DM mode, disable DM mode // when the fragment is not interactive (e.g., a dialog shows up). mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); } super.onPause(); }

Weitere Beispiele finden Sie in der Projekt RotaryPlayground.

Aktivitätsansicht

Bei Verwendung einer ActivityView:

  • ActivityView sollte nicht fokussierbar sein.
  • (Android 11 QPR3, Android 11 Car, in Android 11 eingestellt)
    Der Inhalt der ActivityView MUSS eine FocusParkingView enthalten. als erste fokussierbare Ansicht und ihre app:shouldRestoreFocus Attribut MUSS false lauten.
  • Der Inhalt von ActivityView sollte keine android:focusByDefault Aufrufe.

Für den Nutzer sollten ActivityViews keine Auswirkungen auf die Navigation haben, außer diesem Fokus Areas dürfen keine ActivityView umfassen. Mit anderen Worten: Sie können keinen einzelnen Schwerpunktbereich haben, enthält Inhalte innerhalb und außerhalb von ActivityView. Wenn Sie keine einen beliebigen FocusAreas (FocusAreas) für ActivityView (Basis der Ansichtshierarchie in der ActivityView gilt als impliziter Fokusbereich.

Tasten, die sich durch Gedrückthalten bedienen

Die meisten Schaltflächen lösen Aktionen aus, wenn sie angeklickt werden. Einige Tasten funktionieren, wenn sie gedrückt gehalten werden. Die Tasten Vor- und Zurückspulen zum Beispiel funktionieren normalerweise, wenn sie gedrückt gehalten werden. Um eine solche Tasten unterstützen Drehknopf, auf KEYCODE_DPAD_CENTER warten KeyEvents wie folgt:

mButton.setOnKeyListener((v, keyCode, event) ->
{
    if (keyCode != KEYCODE_DPAD_CENTER) {
        return false;
    }
    if (event.getAction() == ACTION_DOWN) {
        mButton.setPressed(true);
        mHandler.post(mRunnable);
    } else {
        mButton.setPressed(false);
        mHandler.removeCallbacks(mRunnable);
    }
    return true;
});

bei denen mRunnable eine Aktion durchführt (z. B. zurückspulen) und sich selbst nach einer Verzögerung ausgeführt werden.

Touch-Modus

Über einen Drehregler können Nutzer auf zwei Arten mit dem Infotainmentsystem in einem Auto interagieren: entweder mithilfe des Drehreglers oder durch Berühren des Bildschirms. Wenn Sie den Drehregler verwenden, ist eine der fokussierbaren Ansichten hervorgehoben. Beim Berühren des Bildschirms wird keine Fokushervorhebung angezeigt. angezeigt wird. Der Nutzer kann jederzeit zwischen den folgenden Eingabemodi wechseln:

  • Drehbar → Touch. Wenn der Nutzer den Bildschirm berührt, verschwindet die Fokushervorhebung.
  • Tippen → Drehknopf. Wenn der Nutzer die Taste in der Mitte bewegt oder drückt, die Hervorhebung erscheint.

Die Zurück- und die Home-Taste haben keine Auswirkungen auf den Eingabemodus.

Drehbare Tag-Verkettungen auf dem bestehenden Android-Konzept der Touchmodus. Sie können View.isInTouchMode() um zu ermitteln, welchen Eingabemodus der Nutzer verwendet. Sie können OnTouchModeChangeListener um auf Änderungen zu warten. Sie können damit zwar Ihre Benutzeroberfläche an den aktuellen Eingabemodus sollten Sie größere Änderungen vermeiden, da diese verwirrend sein können.

Fehlerbehebung

In Apps, die speziell für Touchscreens entwickelt wurden, sind üblicherweise verschachtelte, fokussierbare Ansichten vorhanden. Beispiel: Es könnte ein FrameLayout um ein ImageButton, die beide fokussierbar sind. Das schadet der Berührung zwar nicht, kann jedoch zu einer User Experience bei Drehbewegung, da der Benutzer die Steuerung zweimal drehen muss, um zum zur nächsten interaktiven Ansicht wechseln. Für eine gute Nutzererfahrung empfiehlt Google, entweder die äußere oder die innere Ansicht, aber nicht beides.

Wenn eine Taste oder ein Schalter beim Drücken des Drehreglers nicht mehr im Fokus verliert, wird eine der können folgende Bedingungen zutreffen:

  • Die Taste oder der Schalter wurde deaktiviert (kurz oder für unbegrenzte Zeit) aufgrund des die Schaltfläche gedrückt wird. In beiden Fällen gibt es zwei Möglichkeiten, dieses Problem anzugehen: <ph type="x-smartling-placeholder">
      </ph>
    • Belassen Sie den android:enabled-Status auf true und verwenden Sie einen benutzerdefinierten um die Schaltfläche bzw. den Schalter zu deaktivieren (siehe Benutzerdefinierter Status.
    • Setzen Sie einen Container um die Schaltfläche oder den Schalter und machen Sie den Container fokussierbar. statt auf die Taste oder den Schalter. Der Klick-Listener muss sich auf dem Container befinden.
  • Die Taste oder der Schalter wird ersetzt. Zum Beispiel die Aktion, die ausgeführt wird, wenn der Schalter gedrückt oder der Schalter gedrückt wird, kann eine Aktualisierung der verfügbaren Aktionen auslösen wodurch vorhandene Schaltflächen durch neue ersetzt werden. Dafür gibt es zwei Möglichkeiten: <ph type="x-smartling-placeholder">
      </ph>
    • Anstatt eine neue Schaltfläche oder einen neuen Schalter zu erstellen, legen Sie das Symbol und/oder den Text des vorhandene Schaltfläche oder Schalter.
    • Fügen Sie wie oben einen fokussierbaren Container um die Schaltfläche oder den Schalter hinzu.

Drehspielplatz

RotaryPlayground ist eine Referenz-App für Drehköpfe. Hier erfahren Sie, wie Sie Drehfunktionen in Ihre Apps ein. RotaryPlayground ist in Emulator-Builds und in entwickelt für Geräte mit Android Automotive OS (AAOS).

  • RotaryPlayground-Repository: packages/apps/Car/tests/RotaryPlayground/
  • Versionen: Android 11 QPR3, Android 11 Car, und Android 12

In der RotaryPlayground App werden links die folgenden Tabs angezeigt:

  • Infokarten Die Navigation in Fokusbereichen testen und nicht fokussierbare Elemente überspringen und Texteingabe.
  • Direkte Manipulation: Widgets testen, die einfache und erweiterte Funktionen unterstützen direkten Bearbeitungsmodus. Dieser Tab dient speziell zur direkten Bearbeitung innerhalb des App-Fenster.
  • Manipulation der Sys-Benutzeroberfläche: Widgets testen, die eine direkte Bearbeitung unterstützen in Systemfenstern, in denen nur der einfache direkte Bearbeitungsmodus unterstützt wird.
  • Raster: Drehnavigation mit Z-Muster durch Scrollen testen
  • Benachrichtigung. Testen Sie das Ein- und Ausschalten von Vorabbenachrichtigungen.
  • Scrollen: Testen Sie das Scrollen durch eine Mischung aus fokussierbaren und nicht fokussierbaren Inhalte.
  • WebView Navigation über Links in einem WebView testen.
  • Benutzerdefiniert FocusArea. Testen Sie die FocusArea-Anpassung: <ph type="x-smartling-placeholder">
      </ph>
    • Rundum.
    • android:focusedByDefault und app:defaultFocus
    • .
    • Explizite Ziele für automatische Erinnerungen.
    • Kurzbefehle für Erinnerungen.
    • FocusArea ohne fokussierbare Ansichten.