Das folgende Material richtet sich an App-Entwickler.
Damit Ihre App die Drehung unterstützt, MÜSSEN Sie Folgendes tun:
- Fügen Sie ein
FocusParkingView
in das entsprechende Aktivitätslayout ein. - Stellen Sie sicher, dass die Ansichten fokussierbar oder nicht fokussierbar sind.
- Mit
FocusArea
s können Sie alle fokussierbaren Ansichten mit Ausnahme derFocusParkingView
.
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:
- Tippe unten in der Symbolleiste auf das Dreipunkt-Menü:
<ph type="x-smartling-placeholder"> - Wähle im Fenster mit den erweiterten Steuerelementen Drehrad aus:
<ph type="x-smartling-placeholder">
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
- odereng
-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:
- 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, sodassRotaryService
den Fokus darauf parken kann. , um die Hervorhebung zu entfernen. - Wenn sich nur ein
FocusArea
im aktuellen Fenster befindet, drehen Sie den Controller im FeldFocusArea
führt dazu, dassRotaryService
den Fokus verschiebt von der rechten zur linken (und umgekehrt) zu wechseln. Diese Ansicht hinzufügen in jedem Fenster das Problem beheben. WennRotaryService
den Fokus bestimmtFocusParkingView
ist, kann er feststellen, an diesem Punkt erscheinen, da der Fokus nicht bewegt wird. - Wenn über den Drehknopf eine App gestartet wird, fokussiert Android die erste fokussierbare Ansicht.
Dieser ist immer
FocusParkingView
. DasFocusParkingView
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 Button
s,
in der Regel fokussierbar sind. Andere, z. B. TextView
s und ViewGroup
s,
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:
- So fügen Sie ein benutzerdefiniertes Attribut hinzu:
zu Ihrer Ansicht hinzufügen. Wenn Sie beispielsweise dem benutzerdefinierten Status
state_rotary_enabled
AnsichtsklasseCustomView
, verwenden:<declare-styleable name="CustomView"> <attr name="state_rotary_enabled" format="boolean" /> </declare-styleable>
- 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; }
- 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);
- Ü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; }
- 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
istfalse
. - Damit die Schaltfläche deaktiviert erscheint, verwenden Sie im Hintergrund-Drawable der Ansicht Folgendes:
app:state_rotary_enabled
stattandroid:state_enabled
. Fügen Sie Folgendes hinzu, falls noch nicht geschehen:xmlns:app="http://schemas.android.com/apk/res-auto"
- Wenn die Ansicht in einem Layout deaktiviert ist, ersetzen Sie
android:enabled="false"
durchapp:state_rotary_enabled="false"
und fügen Sie dann den Namespaceapp
hinzu. wie oben beschrieben. - Wenn Ihre Ansicht programmatisch deaktiviert ist, ersetzen Sie Aufrufe von
setEnabled()
mit Aufrufen vonsetRotaryEnabled()
.
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:
- Bei der Verarbeitung von Dreh- und Anstupseraktionen sucht
RotaryService
nach Instanzen vonFocusArea
in der Ansichtshierarchie. - Beim Empfang eines Rotationsereignisses verschiebt
RotaryService
den Fokus auf ein anderes Ansicht, die im selbenFocusArea
hervorgehoben werden kann. - 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 stattdessenapp:wrapAround
(siehe unten), um eine Schleife zu erstellen. - Mit
android:focusedByDefault
können App-Entwickler die Standardfokusansicht im Fenster. Verwenden Sie NICHT dieses Attribut undapp:defaultFocus
(siehe unten) im selbenFocusArea
.
FocusArea
definiert auch einige Attribute zum Anpassen der Drehsteuerung.
Implizite Fokusbereiche können mit diesen Attributen nicht angepasst werden.
- (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/nFocusArea
weitergeleitet. - (Android 11 QPR3, Android 11 Car,
Android 12)
app:defaultFocusOverridesHistory
kann auftrue
gesetzt werden, damit die oben angegebene Ansicht fokussiert wird, auch wenn angezeigt, die auf eine andere Ansicht in dieserFocusArea
fokussiert waren. - (Android 12)
Verwenden Sieapp:nudgeLeftShortcut
,app:nudgeRightShortcut
,app:nudgeUpShortcut
undapp: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
undapp:nudgeShortcutDirection
unterstützte nur eine Anstups-Tastenkombination. - (Android 11 QPR3, Android 11 Car,
Android 12)
Um die Rotation in dieserFocusArea
zu aktivieren,app:wrapAround
kann auftrue
festgelegt werden. Dies wird vor allem verwendet, wenn Ansichten so angeordnet sind, Kreis oder Oval. - (Android 11 QPR3, Android 11 Car,
Android 12)
Um den Abstand der Markierung in dieseFocusArea
,app:highlightPaddingStart
verwenden,app:highlightPaddingEnd
,app:highlightPaddingTop
app:highlightPaddingBottom
,app:highlightPaddingHorizontal
, undapp:highlightPaddingVertical
. - (Android 11 QPR3, Android 11 Car,
Android 12)
So passt du die wahrgenommenen Grenzen vonFocusArea
an, um ein Anstupser-Ziel zu finden: Verwenden Sieapp:startBoundOffset
,app:endBoundOffset
,app:topBoundOffset
,app:bottomBoundOffset
app:horizontalBoundOffset
undapp:verticalBoundOffset
. - (Android 11 QPR3, Android 11 Car,
Android 12)
Um die ID eines Objekts explizit anzugeben, nebenFocusArea
(oder Bereichen) in der angegebenen Richtung, verwenden Sieapp:nudgeLeft
,app:nudgeRight
,app:nudgeUp
undapp: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:
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">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:
- (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 |
Drehbares Scrollen
Wenn deine App RecyclerView
s verwendet, SOLLTEN du Folgendes verwenden:
CarUiRecyclerView
. Dadurch wird sichergestellt, dass Ihre UI
da die Anpassungen eines OEMs für alle CarUiRecyclerView
s 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 entwederAXIS_VSCROLL
oderAXIS_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
AccessibilityEvent
en 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:
- (Android 11 QPR3, Android 11 Car,
Android 12) MUSS auf
KEYCODE_DPAD_CENTER
warten. um in den DM-Modus zu wechseln und auf einKEYCODE_BACK
-Ereignis zu warten, um den DM-Modus zu beenden, in jedem FallDirectManipulationHelper.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.
- Registriere ein
- SOLLTE auf Anstupser-Ereignisse achten (
KEYCODE_DPAD_UP
,KEYCODE_DPAD_DOWN
,KEYCODE_DPAD_LEFT
oderKEYCODE_DPAD_RIGHT
), wenn die Ansicht „Anstupser“ verwenden. - MÜSSEN auf
MotionEvent
s achten und die Anzahl der Drehungen inAXIS_SCROLL
abrufen wenn die Ansicht die Rotation übernehmen möchte. Dafür gibt es mehrere Möglichkeiten: <ph type="x-smartling-placeholder">- </ph>
- Registriere ein
OnGenericMotionListener
. - Erweitern Sie die Ansicht und überschreiben Sie die zugehörige
dispatchTouchEvent()
-Methode.
- Registriere ein
- 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.
- 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 derActivityView
MUSS eineFocusParkingView
enthalten. als erste fokussierbare Ansicht und ihreapp:shouldRestoreFocus
Attribut MUSSfalse
lauten. - Der Inhalt von
ActivityView
sollte keineandroid: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 auftrue
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.
- Belassen Sie den
- 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 dieFocusArea
-Anpassung: <ph type="x-smartling-placeholder">- </ph>
- Rundum.
android:focusedByDefault
undapp:defaultFocus
.
- Explizite Ziele für automatische Erinnerungen.
- Kurzbefehle für Erinnerungen.
FocusArea
ohne fokussierbare Ansichten.