Tworzenie aplikacji

Ten materiał jest przeznaczony dla deweloperów aplikacji.

Aby aplikacja obsługiwała po kolei, MUSISZ:

  1. Umieść FocusParkingView w odpowiednim układzie aktywności.
  2. Zadbaj o to, aby widoki, które można zaznaczyć (lub nie).
  3. Użyj komponentów FocusArea, aby objąć wszystkie widoki, które można zaznaczyć, z wyjątkiem FocusParkingView

Każde z tych zadań znajdziesz poniżej, gdy skonfigurujesz środowisko tworzyć aplikacje z obrotową głową.

Skonfiguruj kontroler obrotowy

Zanim zaczniesz tworzyć aplikacje z obrotami, potrzebujesz kontrolera obrotowego lub alternatywna. Masz do wyboru opisane poniżej opcje.

Emulator

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

Możesz też użyć aosp_car_x86_64-userdebug.

Aby uzyskać dostęp do emulowanego kontrolera obrotowego:

  1. Kliknij 3 kropki na dole paska narzędzi:

    Dostęp do emulowanego kontrolera obrotowego
    Rysunek 1. Dostęp do emulowanego kontrolera obrotowego
  2. W rozszerzonym oknie sterowania wybierz Obroty samochodu:

    . Wybierz pokrętło samochodowe
    Rysunek 2. Wybierz karuzelę

Klawiatura USB

  • Podłącz klawiaturę USB do urządzenia z systemem operacyjnym Android Automotive (AAOS). W niektórych przypadkach zapobiega wyświetlaniu klawiatury ekranowej.
  • Użyj kompilacji userdebug lub eng.
  • Włącz filtrowanie kluczowych zdarzeń:
    adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
    
  • W tabeli poniżej znajdziesz informacje o kluczach odpowiadających poszczególnym działaniom:
    Klucz Obrotowe
    P Obróć w lewo
    E Obróć w prawo
    A Posuń w lewo
    D Posuń w prawo
    W Posuń w górę
    S Posuń w dół
    F lub przecinek Przycisk środkowy
    R lub Esc Przycisk Wstecz

Polecenia ADB

Do wprowadzania zdarzeń pokrętła wprowadzania danych możesz używać poleceń car_service. Te polecenia można uruchamiać na urządzeniach z systemem operacyjnym Android Automotive (AAOS) lub w emulatorze.

polecenia dotyczące usługi car_service Pokrętło
adb shell cmd car_service inject-rotary Obróć w lewo
adb shell cmd car_service inject-rotary -c true Obróć w prawo
adb shell cmd car_service inject-rotary -dt 100 50 Kilkakrotnie obróć w lewo (100 ms temu i 50 ms temu)
adb shell cmd car_service inject-key 282 Posuń w lewo
adb shell cmd car_service inject-key 283 Posuń w prawo
adb shell cmd car_service inject-key 280 Posuń w górę
adb shell cmd car_service inject-key 281 Posuń w dół
adb shell cmd car_service inject-key 23 Kliknięcie przycisku środkowego
adb shell input keyevent inject-key 4 Kliknięcie przycisku Wstecz

Kontroler obrotowy OEM

Kiedy Twój kontroler obrotowy jest gotowy, realistycznej opcji. Jest to szczególnie przydatne do testowania szybkiej rotacji.

Widok Parkingu

FocusParkingView to przejrzysty widok Biblioteka Car UI (car-ui-library). Urządzenie RotaryService używa go do obsługi nawigacji za pomocą kontrolera obrotowego. FocusParkingView musi być pierwszym widokiem, który można zaznaczyć w układzie. Musi znajdować się poza wszystkimi elementami FocusArea. Każde okno musi mieć jeden FocusParkingView Jeśli używasz już układu podstawowego biblioteki samochodu, zawierający FocusParkingView, nie musisz dodawać kolejnego FocusParkingView Poniżej znajduje się przykład kodu FocusParkingView w języku: 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>

Powody, dla których potrzebujesz uprawnienia FocusParkingView:

  1. Android nie wyczyści automatycznie ostrości, gdy jest ono ustawione w innym oknie. Jeśli usunąć ostrość z poprzedniego okna, Android zmienia ostrość obrazu w tym oknie, co powoduje jednoczesne skupienie się na dwóch oknach. Dodaję: FocusParkingView może rozwiązać ten problem. Ten widok jest przezroczysty i jest domyślnie wyróżniony jest wyłączona, więc jest niewidoczna dla użytkownika niezależnie od tego, czy jest zaznaczona. Może być skupiony RotaryServicena nimzaparkowany aby usunąć wyróżnienie.
  2. Jeśli w bieżącym oknie jest tylko 1 element FocusArea, obracanie kontrolera w elemencie FocusArea powoduje, że RotaryService przenosi zaznaczenie z widoku po prawej stronie do widoku po lewej stronie (i odwrotnie). Dodawanie tego widoku do każdego okna, może to rozwiązać. Kiedy RotaryService określa ostrość cel to FocusParkingView, może określić, że obwódka w którym można uniknąć zawinięcia, nie poruszając obiektu.
  3. Kiedy pokrętło uruchamia aplikację, Android ustawia pierwszy widok, który można zaznaczyć, czyli zawsze FocusParkingView. FocusParkingView określa optymalny widok, na którym należy się skupić, a następnie stosuje zaznaczenie.

Widoki, do których można przejść

RotaryService opiera się na platformie Androida istniejący koncepcja skupienia się na widoku. Już w czasach, gdy telefony miały klawiaturę fizyczną i pady kierunkowe. Istniejący atrybut android:nextFocusForward jest używany ponownie w przypadku rotacji (patrz Dostosowywanie obszaru fokusu), ale android:nextFocusLeft, android:nextFocusRight, android:nextFocusUp i android:nextFocusDown nie są.

RotaryService skupia się tylko na wyświetleniach, które można zaznaczyć. Niektóre widoki Na przykład Button, można zazwyczaj zaznaczyć. Inne, np. TextView i ViewGroup, zwykle nie są. Widoki, które można kliknąć, są automatycznie zaznaczane, a wyświetlenia są automatycznie jeśli użytkownik ma detektor kliknięć. Jeśli ta automatyczna logika powoduje pożądane działanie fokusy, nie musisz jednoznacznie ustawiać ostrości widoku. Jeśli automatyczna logika nie zadziała aby uzyskać pożądany efekt zaznaczenia, ustaw atrybut android:focusable na true lub false albo automatycznie ustawić ostrość widoku za pomocą funkcji View.setFocusable(boolean) Aby usługa RotaryService mogła skupić się na tym wyświetleniu, MUSI być widoczny widok spełniasz te wymagania:

  • Można zaznaczyć
  • Włączone
  • Widoczne
  • Szerokość i wysokość nie muszą mieć wartości zero.

Jeśli widok nie spełnia wszystkich tych wymagań, np. może to być przycisk, który można zaznaczyć, ale jest wyłączony, użytkownik nie będzie mógł skupić się na nim za pomocą pokrętła. Jeśli chcesz skupić się na wyłączonych widokach, Rozważ użycie stanu niestandardowego zamiast android:state_enabled, aby kontrolować, pojawia się bez wskazania, że Android powinien uznać go za wyłączony. Aplikacja może informować dlaczego widok jest wyłączony po dotknięciu. Jak to zrobić, dowiesz się z następnej sekcji.

Stan niestandardowy

Aby dodać stan niestandardowy:

  1. Aby dodać atrybut niestandardowy: z Twoim widokiem. Aby np. dodać do tagu stan niestandardowy state_rotary_enabled CustomView klasa wyświetlania, użyj:
    <declare-styleable name="CustomView">
        <attr name="state_rotary_enabled" format="boolean" />
    </declare-styleable>
    
  2. Aby śledzić ten stan, dodaj do widoku zmienną instancji wraz z metodami akcesora:
    private boolean mRotaryEnabled;
    public boolean getRotaryEnabled() { return mRotaryEnabled; }
    public void setRotaryEnabled(boolean rotaryEnabled) {
        mRotaryEnabled = rotaryEnabled;
    }
    
  3. Aby odczytać wartość atrybutu podczas tworzenia widoku:
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
    mRotaryEnabled = a.getBoolean(R.styleable.CustomView_state_rotary_enabled);
    
  4. W klasie widoku zastąp metodę onCreateDrawableState(), a następnie w razie potrzeby dodaj stan niestandardowy. Na przykład:
    @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. Skonfiguruj działanie modułu obsługi kliknięć w danym widoku w różny sposób. Na przykład parametr moduł obsługi kliknięć może nic nie zrobić lub może pojawić się powiadomienie, Obecny stan „mRotaryEnabled”: false.
  6. Aby przycisk był wyłączony, w widoku widoku, który można rysować, użyj app:state_rotary_enabled zamiast android:state_enabled. Jeśli jeszcze nie masz tych danych, musisz dodać:
    xmlns:app="http://schemas.android.com/apk/res-auto"
    
  7. Jeśli widok jest wyłączony w jakichkolwiek układach, zastąp android:enabled="false" elementem app:state_rotary_enabled="false", a następnie dodaj przestrzeń nazw app, jak powyżej.
  8. Jeśli widok jest automatycznie wyłączony, zastąp wywołania setEnabled() z połączeniami z numerem setRotaryEnabled().

Obszar skupienia

Użyj narzędzia FocusAreas, aby podzielić widoki, które można zaznaczyć, na bloki i ułatwić nawigację i spójność z innymi aplikacjami. Na przykład jeśli Twoja aplikacja ma pasek narzędzi, należy umieścić w osobnym elemencie FocusArea od reszty aplikacji. Paski kart oraz pozostałe elementy nawigacyjne również powinny być oddzielone od reszty aplikacji. Duże listy powinna zwykle mieć własne FocusArea. W przeciwnym razie użytkownicy muszą przejść całą listę, aby uzyskać dostęp do niektórych widoków.

FocusArea jest podklasą klasy LinearLayout w bibliotece car-ui-biblioteki. Gdy ta funkcja jest włączona, FocusArea rysuje podświetlenie, gdy jeden ze swoich elementów podrzędnych. Więcej informacji: Wyróżnij dostosowanie zaznaczenia.

Gdy tworzysz blok nawigacyjny w pliku układu, jeśli zamierzasz użyć tagu LinearLayout jako kontener dla tego bloku, zamiast tego użyj FocusArea. W przeciwnym razie zawiń bryłę w zasadę FocusArea.

NIE zagnieżdżaj obiektu FocusArea w innym obiekcie FocusArea. Spowoduje to nieokreślone zachowanie nawigacji. Upewnij się, że wszystkie widoki, które można zaznaczyć, są są zagnieżdżone w elemencie FocusArea.

Przykład elementu FocusArea w RotaryPlayground widać poniżej:

<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 działa w ten sposób:

  1. Podczas obsługi działań obracania i przesuwania RotaryService szuka instancji FocusArea w hierarchii widoków.
  2. Po otrzymaniu zdarzenia rotacji RotaryService przenosi zaznaczenie na inne Widok, który może skupić się na tym samym elemencie FocusArea.
  3. Po otrzymaniu powiadomienia RotaryService przenieś zaznaczenie do innego widoku które mogą skupić się w innym (zwykle sąsiednim) FocusArea.

Jeśli w układzie nie umieścisz żadnego elementu FocusAreas, widok główny będzie traktowany jako dyskretnego obszaru. Użytkownik nie może skłaniać do korzystania z aplikacji. Zamiast tego będą obracać widok we wszystkich widokach, które można zaznaczyć, co może być wystarczające w przypadku okien dialogowych.

Dostosowanie fokusu

Za pomocą dwóch standardowych atrybutów Widok można dostosować nawigację pokrętło:

  • android:nextFocusForward umożliwia deweloperom aplikacji określenie rotacji i określ kolejność w danym obszarze. To ten sam atrybut, który służy do sterowania kolejnością kart w przypadku nawigacji za pomocą klawiatury. NIE używaj tego atrybutu do tworzenia pętli. Zamiast tego do utworzenia pętli użyj zasady app:wrapAround (patrz poniżej).
  • android:focusedByDefault umożliwia programistom aplikacji określenie domyślny fokus w oknie. NIE używaj tego atrybutu i app:defaultFocus (patrz poniżej) w tym samym elemencie FocusArea.

FocusArea definiuje również atrybuty pozwalające dostosować nawigację pokrętła. Nie można dostosować za pomocą tych atrybutów obszarów niejawnych.

  1. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocus może służyć do: określają identyfikator widoku podrzędnego z możliwością zaznaczenia, który ma się skupić, gdy użytkownik ponaglenia do tego elementu: FocusArea.
  2. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocusOverridesHistory można ustawić na true, aby skupić się na widoku określonym powyżej, nawet jeśli historii, aby wskazać inny widok w tym elemencie (FocusArea).
  3. (Android 12)
    Użyj tych form płatności: app:nudgeLeftShortcut, app:nudgeRightShortcut. app:nudgeUpShortcut i app:nudgeDownShortcut aby określić identyfikator widoku podrzędnego z możliwością zaznaczenia, który powinien się skupić, gdy ponaglenia w danym kierunku. Aby dowiedzieć się więcej, zapoznaj się z przesuwaj skróty poniżej.

    (Android 11 QPR3, Android 11 Car, wycofane na Androidzie 12) app:nudgeShortcut i app:nudgeShortcutDirection obsługiwały tylko 1 skrót ponaglenia.

  4. (Android 11 QPR3, Android 11 Car, Android 12)
    Aby włączyć obrót wokół elementu FocusArea, app:wrapAround można ustawić na true. Tej opcji używa się zwykle, gdy widoki są rozmieszczone w koło lub owalu.
  5. (Android 11 QPR3, Android 11 Car, Android 12)
    Aby dostosować dopełnienie podświetlenia w w FocusArea, użyj app:highlightPaddingStart, app:highlightPaddingEnd, app:highlightPaddingTop, app:highlightPaddingBottom, app:highlightPaddingHorizontal, i app:highlightPaddingVertical.
  6. (Android 11 QPR3, Android 11 Car, Android 12)
    Aby dostosować postrzegane granice tej wartości FocusArea w celu znalezienia celu zachęty, użyj app:startBoundOffset, app:endBoundOffset, app:topBoundOffset, app:bottomBoundOffset, app:horizontalBoundOffset i app:verticalBoundOffset.
  7. (Android 11 QPR3, Android 11 Car, Android 12)
    Aby wyraźnie określić identyfikator elementu przylegające FocusArea (lub obszary) w podanych kierunkach, użyj app:nudgeLeft, app:nudgeRight, app:nudgeUp i app:nudgeDown. Tej opcji należy używać, gdy domyślnie używane jest wyszukiwanie geometryczne nie znajdzie żądanego miejsca docelowego.

Zachęcanie zwykle powoduje przejście między obszarami skupienia. Jednak dzięki skrótom ponagleń ponaglenia czasami najpierw pojawiają się w obrębie FocusArea, więc użytkownik może potrzebować aby dwukrotnie przesunąć palcem do następnego elementu FocusArea. Skróty przesuwania są przydatne gdy FocusArea zawiera długą listę, po której następuje Pływający przycisk polecenia, Jak w tym przykładzie:

Posuń skrót
Rysunek 3. Skrót do przesuwania

Bez skrótu ponaglenia użytkownik musiałby przewijać listę, by dotrzeć do przycisk typu FAB.

Zaznacz dostosowanie zaznaczenia

Jak wspomnieliśmy powyżej, RotaryService opiera się na dotychczasowej koncepcji platformy Androida – zaznaczenie. Gdy użytkownik obraca element i podkreśla go, RotaryService przesuwa zaznaczenie skupienie jednego widoku i usunięcie ostrości na drugim. Jeśli widok jest aktywny na Androidzie, widok:

  • ma osobne wyróżnienie, a Android wybiera najciekawszy element widoku.
  • Nie określa wyróżnienia, a domyślne podświetlenie nie jest wyłączone, Android ustawia domyślne wyróżnienie widoku.

Aplikacje obsługujące dotyk zazwyczaj nie ustawiają odpowiedniego wyróżnienia.

Domyślny wyróżniony wyróżniony element jest dostarczany przez platformę Androida i można go zmienić. przez OEM. Deweloperzy aplikacji otrzymują tę wiadomość, jeśli używany przez nich motyw pochodzi z aplikacji Theme.DeviceDefault

Aby zadbać o wygodę użytkowników, w miarę możliwości korzystaj z domyślnego wyróżnienia. Jeśli potrzebujesz wyróżniania o niestandardowym kształcie (np. okrągłego lub pigułkowego), używając motywu niepochodzącego od Theme.DeviceDefault, użyj biblioteki car-ui-library zasobów, aby określić własne wyróżnienie dla każdego widoku.

Aby określić niestandardowe wyróżnienie w widoku, zmień rysowane tło lub pierwszy plan na element rysowalny, który różni się, gdy jest ustawiony widok. Zwykle należy zmienić w tle. Oto element rysowalny (jeśli jest używany jako tło dla widoku kwadratowego): tworzy okrągłe wyróżnienie:

<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) Odwołania do zasobów w przykładzie (pogrubienie) powyżej wskazują zasoby zdefiniowane przez bibliotekę car-ui-library. OEM zastępuje je, aby zachować spójność. z wybranym przez nich domyślnym wyróżnieniem. Zapewnia to, że ostrość jest kolorem, szerokości kreski itd. nie zmieniają się, gdy użytkownik przechodzi między widokami z niestandardowym zaznaczeniem oraz widok z domyślnym wyróżnieniem. Ostatni element to fala używana dotykowo. Domyślne wartości użyte dla pogrubionych zasobów są następujące:

Domyślne wartości zasobów pogrubionych
Rysunek 4. Domyślne wartości pogrubionych zasobów

Dodatkowo niestandardowe wyróżnienie jest wywoływane, gdy na przycisku zostanie nałożony aby zwrócić na niego uwagę użytkownika, jak widać w poniższym przykładzie. Może to sprawić, że trudne do zauważenia wyróżnienie. W takiej sytuacji niestandardowe wyróżnienie za pomocą kolory dodatkowe:

Jednolity kolor tła
  • (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

Na przykład:

Zaznaczony, nienaciśnięty Zaznaczony, naciśnięty
zaznaczony, nienaciśnięty zaznaczony, naciśnięty

Przewijanie obrotowe

Jeśli aplikacja używa znaczników RecyclerView, NALEŻY użyć CarUiRecyclerView. Dzięki temu będziesz mieć pewność, że Twój interfejs użytkownika jest zgodny z innych, ponieważ zmiany wprowadzone przez producenta OEM dotyczą wszystkich CarUiRecyclerView.

Jeśli wszystkie elementy na liście można zaznaczyć, nie musisz nic więcej robić. Nawigacja pokrętła powoduje przesuwanie zaznaczenia po elementach listy i przewijanie listy aby nowo zaznaczony element był widoczny.

(Android 11 QPR3, Android 11 Car, Android 12)
czy film zawiera treści, które można zaznaczyć i które nie są skupione lub jeśli na wszystkich elementach nie można ustawić ostrości, można włączyć przewijanie pokrętło, Użytkownik może za pomocą kontrolera obrotowego stopniowo przewijać listę bez pomijania elementy, których nie można zaznaczyć. Aby włączyć przewijanie pokrętło, ustaw app:rotaryScrollEnabled dla atrybutu true.

(Android 11 QPR3, Android 11 Car, Android 12)
Możesz włączyć przewijanie pokrętło w każdej przewijany, w tym avCarUiRecyclerView, z Metoda setRotaryScrollEnabled() w CarUiUtils. W takim przypadku musisz:

  • Umożliwia zaznaczanie widoku przewijanego, tak aby można go było zaznaczyć, gdy żaden widoczne są
  • Wyłącz domyślne wyróżnienie w widoku przewijanym, wywołując setDefaultFocusHighlightEnabled(false), tak aby widok, który można przewijać nie jest skupiona,
  • Upewnij się, że widok przewijany jest zaznaczony przed jego elementami podrzędnymi, wywołując setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
  • Nasłuchuj zdarzeń MotionEvents, używając SOURCE_ROTARY_ENCODER i jednego z tych elementów: AXIS_VSCROLL lub AXIS_HSCROLL, aby wskazać odległość do przewinięcia, a przycisk kierunek (przez znak).

Gdy na urządzeniu CarUiRecyclerView włączone jest przewijanie pokrętło, a użytkownik obraca widok w obszarze, w którym nie ma widoków, do których można przejść, pasek przewijania zmieni kolor z szarego na niebieski, jak co wskazuje, że pasek przewijania jest aktywny. Jeśli chcesz, możesz zastosować podobny efekt.

Zdarzenia MotionEvents są takie same jak te generowane przez pokrętło myszy, oprócz źródła.

Tryb bezpośredniej manipulacji

Normalnie ponaglenia i obrót poruszają się po interfejsie, natomiast naciśnięcie przycisku środkowego podejmować odpowiednie działania, chociaż nie zawsze tak jest. Jeśli na przykład użytkownik chce dostosować parametr głośności alarmu, za pomocą pokrętła można przejść do suwaka głośności, nacisnąć Przycisk środkowy, obróć kontroler, aby dostosować głośność alarmu, a następnie naciśnij przycisk Wstecz aby wrócić do nawigacji. Jest to tzw. tryb manipulacji bezpośredniej. W tym kontroler obrotowy służy do bezpośredniej interakcji z widokiem, a nie do nawigacji.

Wdrożenie czatu na jeden z 2 sposobów Jeśli potrzebujesz tylko obsługi obracania i widoku manipulacja odpowiada odpowiedziom ACTION_SCROLL_FORWARD i ACTION_SCROLL_BACKWARD AccessibilityEvent we właściwy sposób, użyj mechanizm prosty. W przeciwnym razie użyj mechanizmu zaawansowanego.

W oknach systemowych jedyną opcją jest mechanizm prosty, aplikacje mogą korzystać z jednego z tych mechanizmów.

Prosty mechanizm

(Android 11 QPR3, Android 11 Car, Android 12)
Aplikacja powinna zadzwonić DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable) RotaryService rozpoznaje, kiedy użytkownik jest w trybie czatu, i przechodzi w ten tryb, gdy użytkownik naciska przycisk Środkowy podczas aktywnego wyświetlania widoku. W trybie czatu wykonywane są obroty ACTION_SCROLL_FORWARD lub ACTION_SCROLL_BACKWARD i zamyka tryb czatu gdy użytkownik naciśnie przycisk Wstecz. Mechanizm prosty przełącza wybrany stan widoczne przy przechodzeniu do trybu czatu i wyjściu z niego.

Aby dać wizualną informację, że użytkownik korzysta z trybu czatu, zmień widok po wybraniu. Na przykład zmień tło, gdy Obecny stan „android:state_selected”: true.

Mechanizm zaawansowany

Aplikacja określa, kiedy RotaryService wchodzi w tryb czatu i z niego opuszcza. Aby uzyskać spójność interfejs, naciśnięcie przycisku środkowego z zaznaczonym widokiem czatu powinno przejść do trybu czatu a przycisk Wstecz powinien wyjść z trybu czatu. Jeśli nie używasz środkowego przycisku ani ponaglenia, mogą być alternatywnymi sposobami na wyłączenie trybu czatu. W aplikacjach takich jak Mapy Google przycisk do reprezentowania Za pomocą czatu można przejść do trybu czatu.

Aby obsługiwać zaawansowany tryb czatu, widok:

  1. (Android 11 QPR3, Android 11 Car, Android 12) MUSI nasłuchiwać KEYCODE_DPAD_CENTER aby przejść w tryb czatu i nasłuchiwać zdarzenia KEYCODE_BACK, aby wyjść z trybu czatu; wywołanie DirectManipulationHelper.enableDirectManipulationMode() w każdym przypadku. Aby nasłuchiwać tych zdarzeń, wykonaj jedną z tych czynności:
    • Zarejestruj OnKeyListener.
    • lub
    • Rozszerz widok, a następnie zastąp jego metodę dispatchKeyEvent().
  2. POWINNA nasłuchiwać zdarzeń ponagleń (KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT lub KEYCODE_DPAD_RIGHT), jeśli widok powinien ponaglenia dotyczące obsługi aplikacji.
  3. MUSI nasłuchiwać MotionEvent s, a liczba rotacji uzyskać AXIS_SCROLL jeśli widok ma obsługiwać obrót. Możesz to zrobić na kilka sposobów:
    1. Zarejestruj OnGenericMotionListener.
    2. Rozszerz widok i zastąp jego metodę dispatchTouchEvent().
  4. Aby uniknąć utknięcia w trybie DM, MUSI wyjść z trybu DM, gdy fragment lub aktywność w widoku danych należy do nie jest interaktywny.
  5. MUSI wizualną wskazówkę wskazującą, że widok jest w trybie czatu.

Poniżej znajduje się przykład widoku niestandardowego, który używa trybu czatu do przesuwania i powiększania mapy:

/** 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(); }

Więcej przykładów znajdziesz w RotaryPlayground projekt.

Widok aktywności

Gdy korzystasz z ActivityView:

  • Nie można zaznaczyć elementu ActivityView.
  • (Android 11 QPR3, Android 11 Car, wycofane na Androidzie 11)
    Treść ActivityView MUSI zawierać FocusParkingView jako pierwszy widok, który można zaznaczyć, a app:shouldRestoreFocus MUSI mieć wartość false.
  • Zawartość pola ActivityView nie powinna zawierać parametru Liczba wyświetleń: android:focusByDefault.

W przypadku użytkownika obiekty ActivityView powinny mieć wyłącznie wpływ na nawigację Obszary nie mogą obejmować obiektów ActivityView. Innymi słowy, nie można mieć jednego obszaru działalności, ma treść wewnątrz i na zewnątrz elementu ActivityView. Jeśli nie dodasz do obszaru ActivityView, który jest głównym elementem hierarchii widoków ActivityView jest uważany za obszar niejawny.

Przyciski, które działają po przytrzymaniu

Większość przycisków powoduje wykonywanie określonych działań po kliknięciu. Niektóre przyciski działają po przytrzymaniu. Na przykład przyciski „Przewiń do przodu” i „Przewiń do tyłu” zwykle działają po przytrzymaniu. Aby takie działania przyciski obsługują pokrętło; nasłuchiwanie: KEYCODE_DPAD_CENTER KeyEvents w następujący sposób:

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

W tym celu mRunnable wykonuje działanie (np. przewija do tyłu) i zaplanuje: być uruchamiane z opóźnieniem.

Tryb dotykowy

Użytkownicy mogą za pomocą kontrolera obrotowego wchodzić w interakcję z głośnikiem w samochodzie na 2 sposoby: za pomocą pokrętła lub ekranu. Używając kontrolera obrotowego, jeden z widoków, do których można przejść. Po dotknięciu ekranu brak zaznaczenia Użytkownik może w każdej chwili przełączyć się między tymi trybami wprowadzania:

  • Obracanie → dotyk. Gdy użytkownik dotknie ekranu, wyróżnienie znika.
  • Dotknij → pokrętło. Gdy użytkownik przechyla, obróci lub naciśnie przycisk środkowy, pojawi się wyróżnienie.

Przyciski Wstecz i Ekran główny nie mają wpływu na tryb wprowadzania.

Obrotowe przeróbki oparte na dotychczasowej koncepcji Androida tryb dotykowy. Za pomocą View.isInTouchMode() aby określić, którego trybu wprowadzania używa użytkownik. Za pomocą OnTouchModeChangeListener by monitorować zmiany. Pozwala to dostosować interfejs użytkownika do aktualnego należy unikać wprowadzania dużych zmian, ponieważ mogą one być niepokojące.

Rozwiązywanie problemów

W aplikacjach obsługujących dotyk często występują zagnieżdżone widoki, które można zaznaczyć. Na przykład może być FrameLayout wokół elementu ImageButton, które da się zaznaczyć. Nie szkodzi to dotyku, ale może powodować obniżenie jakości ponieważ użytkownik musi dwukrotnie obracać kontroler, kolejny interaktywny widok. Aby zadbać o wygodę użytkowników, zalecamy wykonanie jednej z tych czynności: że można wybrać widok zewnętrzny lub wewnętrzny, ale nie oba jednocześnie.

Jeśli przycisk lub przełącznik traci ostrość po naciśnięciu pokrętła, jedno z mogą obowiązywać następujące warunki:

  • Przycisk lub przełącznik są wyłączane (na krótko lub bezterminowo) z powodu podczas naciśnięcia przycisku. W obu przypadkach możesz to zrobić na 2 sposoby:
    • W polu android:enabled pozostaw stan true i użyj wartości niestandardowej. aby wyszarzać przycisk lub przełączyć go na inny stan, tak jak to opisano w Stan niestandardowy.
    • Użyj kontenera, aby otoczyć przycisk lub przełącznik i umożliwić jego zaznaczenie zamiast przycisku lub przełącznika. (Detektor kliknięć musi znajdować się w kontenerze).
  • Wymieniamy przycisk lub przełącznik. Na przykład działanie podjęte, gdy przycisk naciśnięcie lub przestawienie przełącznika może spowodować odświeżenie dostępnych działań które powoduje zastąpienie istniejących przycisków nowymi. Możesz to zrobić na 2 sposoby:
    • Zamiast tworzyć nowy przycisk lub przełącznik, ustaw ikonę i/lub tekst przycisku istniejącego przycisku lub przełącznika.
    • Tak jak powyżej, wokół przycisku lub przełącznika dodaj kontener, który można zaznaczyć.

RotaryPlayground

RotaryPlayground to aplikacja referencyjna dotycząca rotacji. Dowiedz się, jak zintegrować pokrętła i funkcji. Interfejs RotaryPlayground jest uwzględniony w kompilacjach emulatora i w kompilacje na urządzenia z systemem operacyjnym Android Automotive (AAOS).

  • RotaryPlayground repozytorium: packages/apps/Car/tests/RotaryPlayground/
  • Wersje: Android 11 QPR3, Android 11 Car, oraz Android 12

Po lewej stronie aplikacji RotaryPlayground są wyświetlane te karty:

  • Karty. Testuj poruszanie się po obszarach, na których chcesz się skupić, i pomijanie elementów, których nie można zaznaczyć i tekstu.
  • Manipulowanie bezpośrednie. Testuj widżety, które obsługują proste i zaawansowane i trybu bezpośredniej manipulacji. Ta karta jest przeznaczona do bezpośredniej manipulacji w w oknie aplikacji.
  • Manipulowanie interfejsem Sys. Testuj widżety, które obsługują bezpośrednie manipulacje w oknach systemowych, w których obsługiwany jest tylko prosty tryb manipulacji bezpośredniej.
  • Siatka. Przetestuj pokrętło w formacie Z z przewijaniem.
  • Powiadomienie. Przetestuj przypominanie powiadomień z ostrzeżeniem.
  • Przewiń. Przetestuj przewijanie treści, które można zaznaczyć i które nie można zaznaczyć treści.
  • WebView: Przetestuj nawigację po linkach w: WebView.
  • Niestandardowy wymiar FocusArea. Testowanie dostosowania FocusArea:
    • Podsumowanie
    • android:focusedByDefaultapp:defaultFocus
    • .
    • Bezpośrednie cele ponagleń.
    • Posuń skróty.
    • FocusArea bez widoków, do których można przejść.