Korzystaj z biblioteki car-ui-lib
, aby wprowadzać spójne funkcje multimedialne w pojazdach
(IVI). Dzięki tym ćwiczeniom w Codelabs poznasz car-ui-lib
i dowiesz się, jak
za pomocą nakładek zasobów środowiska wykonawczego (RRO) w celu dostosowania komponentów w bibliotece
Czego się nauczysz
Instrukcje:
- Dodaj komponenty
car-ui-lib
do swojej aplikacji na Androida. - Używaj Gradle do tworzenia aplikacji na Androida i RRO.
- Używaj RRO w
car-ui-lib
.
To ćwiczenie w Codelabs nie opisuje szczegółowo, jak działają RRO. Zobacz zmieniać wartość zasobów aplikacji w czasie działania; Rozwiązywanie problemów z nakładkami zasobów środowiska wykonawczego aby dowiedzieć się więcej.
Zanim rozpoczniesz
Wymagania wstępne
Zanim zaczniesz, upewnij się, że:
Komputer z wierszem poleceń (komputer z systemem Linux, Mac lub Windows z w podsystemie Windows dla systemu Linux).
Podłączone do komputera urządzenie z Androidem lub emulator. Zobacz Pobierz aplikację źródłową na Androida. Utwórz Androida
Podstawowa wiedza na temat RRO.
Utwórz nową aplikację na Androida
Czas trwania: 15 minut
W tej sekcji utworzysz nowy projekt Android Studio.
W Android Studio utwórz aplikację za pomocą interfejsu
EmptyActivity
.Rysunek 1.Tworzenie pustej aktywności Nazwij aplikację
CarUiCodelab
i wybierz język Java. Dostępne opcje i w razie potrzeby wybierz lokalizację pliku. Zaakceptuj domyślne wartości dla parametru pozostałych ustawień.Rysunek 2. Nazwij aplikację Zastąp
activity_main.xml
tym blokiem kodu:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Ten blok kodu wyświetla ciąg
sample_text
, który nie został zdefiniowany.Dodaj ciąg zasobów
sample_text
i ustaw go na „Hello, World!” wstrings.xml
. Aby otworzyć ten plik, wybierz aplikacja > src > główny > res > wartości > string.xml.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
Aby utworzyć aplikację, w prawym górnym rogu kliknij zielony przycisk Zagraj. Robię to automatycznie instaluje plik APK w emulatorze lub na urządzeniu z Androidem za pomocą Gradle.
Nowa aplikacja powinna otworzyć się automatycznie w emulatorze lub na urządzeniu z Androidem. Jeśli
nie, otwórz aplikację CarUiCodelab
z poziomu menu z aplikacjami, który jest teraz zainstalowany.
Wygląda on tak:
![Otwórz nową aplikację CarUiCodelab](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=pl)
Dodawanie car-ui-lib do aplikacji na Androida
Czas trwania: 15 minut
Dodaj car-ui-lib
do swojej aplikacji:
Aby dodać zależność
car-ui-lib
do plikubuild.gradle
projektu: wybierz aplikacja > build.gradle. Zależności powinny wyglądać tak:dependencies { implementation 'com.android.car.ui:car-ui-lib:2.0.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' }
Używanie komponentów car-ui-lib w aplikacji na Androida
Teraz gdy masz już aplikację car-ui-lib
, dodaj do niej pasek narzędzi.
W pliku
MainActivity.java
zastąp metodęonCreate
:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the toolbar controller instance. ToolbarController toolbar = CarUi.getToolbar(this); // Set the title on toolbar. toolbar.setTitle(getTitle()); // Set the logo to be shown with the title. toolbar.setLogo(R.mipmap.ic_launcher_round); }
Pamiętaj, aby zaimportować
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Aby użyć motywu
Theme.CarUi.WithToolbar
, wybierz aplikacja > src > główna > Plik AndroidManifest.xml, a następnie zaktualizujAndroidManifest.xml
będą wyglądać tak:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.caruicodelab"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.CarUi.WithToolbar" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Aby utworzyć aplikację, naciśnij zielony przycisk Zagraj tak jak poprzednio.
Dodaj RRO do aplikacji
Czas trwania: 30 minut
Jeśli korzystasz już z RRO, przejdź do następnego sekcji, Dodaj do aplikacji kontroler uprawnień. W przeciwnym razie, aby poznać podstawowe informacje na temat RRO, zapoznaj się z artykułem zmieniać wartość zasobów aplikacji w czasie działania;
Dodaj kontroler uprawnień do aplikacji
Aby kontrolować, które zasoby są nakładane na pakiety RRO, dodaj plik o nazwie
overlayable.xml
do folderu /res
aplikacji. Ten plik służy jako uprawnienie
między aplikacją (elementem docelowym) a pakietem RRO (nakładką).
Dodaj
res/values/overlayable.xml
do swojej aplikacji i skopiuj tę treść do pliku:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Ponieważ ciąg
sample_text
musi być nakładany przez RRO, umieść makro w nazwie zasobu w plikuOverlayable.xml aplikacji.Twój plik z
overlayable.xml
MUSI znajdować się w regionieres/values/
. Jeśli nie, parametrOverlayManagerService
nie może go znaleźć.Dowiedz się więcej o zasobach, które można nakładać, i o tym, jak można je skonfigurowane, patrz Ograniczanie możliwości nakładania .
Utwórz pakiet RRO
W tej sekcji utworzysz pakiet RRO, aby zmienić wyświetlany powyżej ciąg znaków z filmu „Hello, World!” do „Hello World RRO”.
Aby utworzyć nowy projekt, wybierz Plik > Nowe > Nowy projekt. Koniecznie wybierz Brak aktywności zamiast pustej aktywności, ponieważ pakiety RRO zawierają i tylko zasoby.
Twoje konfiguracje są podobne do tych na ilustracji poniżej. lokalizacja, w której są zapisywane, może się różnić:
Po utworzeniu nowego projektu
CarUiRRO
zadeklaruj go jako RRO przez modyfikacjęAndroidManifest.xml
.<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.caruirro"> <application android:hasCode="false" /> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> <overlay android:targetPackage="com.example.caruicodelab" android:targetName="CarUiCodelab" android:isStatic="false" android:resourcesMap="@xml/sample_overlay" /> </manifest>
Powoduje to błąd w zasadzie
@xml/sample_overlay
.resourcesMap
mapuje nazwy zasobów z pakietu docelowego na pakiet RRO.Skopiuj ten blok kodu do
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Dodaj
sample_text
do…/res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
Aby utworzyć wartość docelową RRO, naciśnij zielony przycisk Zagraj w celu utworzenia Gradle. ale możesz utworzyć własną wersję RRO w emulatorze lub na urządzeniu z Androidem.
Aby sprawdzić, czy RRO jest prawidłowo zainstalowane, uruchom polecenie:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
To polecenie wyświetla przydatne informacje o stanie pakietów RRO w systemie.
[ ]
oznacza, że RRO jest zainstalowana i gotowa do aktywacji.---
oznacza, że RRO jest zainstalowana, ale zawiera błędy.[X]
oznacza, że RRO została zainstalowana i aktywowana.
Jeśli RRO zawiera błędy, zapoznaj się z Rozwiązywanie problemów z nakładkami zasobów środowiska wykonawczego zanim przejdziesz dalej.
Aby włączyć RRO i sprawdzić, czy jest włączony:
shell:~$ adb shell cmd overlay enable --user current com.example.caruirro shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [x] com.example.caruirro
Aplikacja wyświetli ciąg „Hello World RRO”.
![Witaj świecie, RRO!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=pl)
Gratulacje! Udało Ci się utworzyć pierwszą reklamę RRO.
Jeśli używasz RRO, warto używać narzędzia Android Asset Packaging Tool (AAPT2)
flagi --no-resource-deduping
i --no-resource-removal
opisane w
Opcje linków.
W tym ćwiczeniu w programie nie musisz dodawać flag, ale zalecamy ich użycie
w RRO, aby uniknąć usuwania zasobów (i rozwiązywania problemów). Ty
możesz je dodać do pliku RRO build.gradle
w ten sposób:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Więcej informacji o tych flagach znajdziesz na stronie Utwórz pakiet AAPT2
Modyfikowanie komponentów car-ui-lib
za pomocą RRO w aplikacji na Androida
Na tej stronie dowiesz się, jak używać nakładki zasobów środowiska wykonawczego do
modyfikować komponenty z biblioteki car-ui-lib
w aplikacji na Androida.
Ustaw kolor tła paska narzędzi
Czas trwania: 15 minut
Aby zmienić kolor tła paska narzędzi:
Dodaj poniższą wartość do aplikacji RRO i ustaw jasność zasobu zielony (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
Biblioteka
car-ui-lib
zawiera zasób o nazwiecar_ui_toolbar_background
Gdy zasób znajdzie się w sekcji konfiguracji RRO, pasek narzędzi nie zmienia się, ponieważ błędna wartość reklamy są kierowane.W polu
AndroidManifest.xml
dla RRO zaktualizujtargetName
, tak by wskazywałcar-ui-lib
:… android:targetName="car-ui-lib" …
Musisz utworzyć nowy pakiet RRO dla każdego pakietu docelowego, który chcesz w nim kierować. Na przykład przy tworzeniu nakładek dla dwóch różnych celów musisz utworzyć dwa pliki APK nakładane.
Zbuduj, zweryfikuj, zainstaluj i włącz RRO w taki sam sposób jak wcześniej.
Twoja aplikacja wygląda tak:
![Nowy kolor tła paska narzędzi Toolbar](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=pl)
Układy i style RRO
Czas trwania: 15 minut
W tym ćwiczeniu tworzysz nową aplikację podobną do tej, którą stworzyłeś wcześniej. Ten umożliwia nakładanie się układu. Wykonaj te same czynności co poprzednio lub zmodyfikuj istniejącej aplikacji.
Pamiętaj, aby dodać do pliku
overlayable.xml
te wiersze:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> <item type="layout" name="activity_main"/> <item type="id" name="textView"/> </policy> </overlayable> </resources>
Sprawdź, czy
activity_main.xml
wygląda tak:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
W aplikacji RRO utwórz
res/layout/activity_main.xml
i dodaj do :<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" android:textAppearance="@style/TextAppearance.CarUi" android:layout_gravity="center_vertical|center_horizontal"/> </FrameLayout>
Zaktualizuj aplikację
res/values/styles.xml
, aby dodać nasz styl do RRO:<?xml version="1.0" encoding="utf-8"?> <resources> <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault"> <item name="android:textColor">#0f0</item> <item name="android:textSize">100sp</item> </style> </resources>
Zmień
targetName
wAndroidManifest.xml
, by wskazywał nazwę nowa aplikacja:… android:targetName="CarUiCodelab" …
Dodaj zasoby do pliku
sample_overlay.xml
w RRO:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> <item target="id/textView" value="@id/textView"/> <item target="layout/activity_main" value="@layout/activity_main"/> </overlay>
Skompiluj i zainstaluj aplikację oraz wskaźnik RRO w taki sam sposób jak wcześniej (zielony przycisk Play). ). Pamiętaj, aby włączyć RRO.
Aplikacja i RRO renderują się w ten sposób. Tekst RRO „Hello World” ma kolor zielony i jest jest wyśrodkowany zgodnie z wartością RRO układu.
![Hello World](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=pl)
Dodaj CarUiRecyclerView do swojej aplikacji
Czas trwania: 15 minut
Interfejs CarUiRecyclerView
udostępnia interfejsy API umożliwiające dostęp do RecyclerView
które są dostosowywane na podstawie materiałów z car-ui-lib
. Na przykład: CarUiRecyclerView
sprawdza flagę w czasie działania, aby określić, czy pasek przewijania powinien być włączony
i wybiera odpowiedni układ.
![Kontener CarUiRecyclerViewContainer](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=pl)
Aby dodać usługę
CarUiRecyclerView
, dodaj ją do aplikacjiactivity_main.xml
iMainActivity.java
plików. Możesz utworzyć nową aplikację od zera lub modyfikować istniejącą aplikację. Jeśli modyfikujesz istniejącą aplikację, pamiętaj, aby usunąć niezadeklarowane zasoby z projektuoverlayable.xml
.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <com.android.car.ui.recyclerview.CarUiRecyclerView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
Może pojawić się ten błąd, który możesz zignorować:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Jeśli zajęcia są poprawnie napisane i dodano
car-ui-lib
jako możesz utworzyć i skompilować pakiet apk. Aby usunąć ten błąd, wybierz Plik > Unieważnij pamięci podręczne, a następnie kliknij Unieważnij i uruchom ponownie.Dodaj do
MainActivity.java
te elementypackage com.example.caruicodelab; import android.app.Activity; import android.os.Bundle; import com.android.car.ui.core.CarUi; import com.android.car.ui.recyclerview.CarUiContentListItem; import com.android.car.ui.recyclerview.CarUiListItem; import com.android.car.ui.recyclerview.CarUiListItemAdapter; import com.android.car.ui.recyclerview.CarUiRecyclerView; import com.android.car.ui.toolbar.ToolbarController; import java.util.ArrayList; /** Activity with a simple car-ui layout. */ public class MainActivity extends Activity { private final ArrayList<CarUiListItem> mData = new ArrayList<>(); private CarUiListItemAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ToolbarController toolbar = CarUi.getToolbar(this); toolbar.setTitle(getTitle()); toolbar.setLogo(R.mipmap.ic_launcher_round); CarUiRecyclerView recyclerView = findViewById(R.id.list); mAdapter = new CarUiListItemAdapter(generateSampleData()); recyclerView.setAdapter(mAdapter); } private ArrayList<CarUiListItem> generateSampleData() { for (int i = 0; i < 20; i++) { CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.ICON); item.setTitle("Title " + i); item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT); item.setIcon(getDrawable(R.drawable.ic_launcher_foreground)); item.setBody("body " + i); mData.add(item); } return mData; }
Skompiluj i zainstaluj aplikację tak jak poprzednio.
Wyświetlana jest teraz CarUiRecyclerView
:
![Widok systemu CarUiRecyclerView](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=pl)
Aby usunąć pasek przewijania, użyj RRO
Czas trwania: 10 minut
To ćwiczenie pokazuje, jak za pomocą RRO usunąć pasek przewijania
CarUiRecyclerView
W RRO dodaj i zmodyfikuj te pliki:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.caruirro"> <application android:hasCode="false" /> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> <overlay android:targetPackage="com.example.caruicodelab" android:targetName="car-ui-lib" android:isStatic="false" android:resourcesMap="@xml/sample_overlay" /> </manifest>
res/values/bools.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <bool name="car_ui_scrollbar_enable">false</bool> </resources>
Zasób
car_ui_scrollbar_enable
jest zasobem logicznymcar-ui-lib
, który określa, czy samochód optymalizuje pasek przewijania (w górę i w dół) wCarUiRecyclerView
jest albo nie ma. Gdy ustawisz wartośćfalse
,CarUiRecyclerView
działa jakRecyclerView
AndroidaX.res/xml/sample_overlay.xml
<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="bool/car_ui_scrollbar_enable" value="@bool/car_ui_scrollbar_enable"/> </overlay>
Skompiluj i zainstaluj aplikację tak jak poprzednio. Pasek przewijania został usunięty z
CarUiRecyclerView
:
![CarUiRecyclerView bez paska przewijania](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=pl)
Użyj układu, aby nakładać na pasek przewijania CarUiRecyclerView
Czas trwania: 15 minut
W tym ćwiczeniu zmienisz układ paska przewijania CarUiRecyclerView
.
Dodaj i zmodyfikuj te pliki w aplikacji RRO.
res/layout/car_ui_recycler_view_scrollbar.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="112dp" android:layout_height="match_parent" android:id="@+id/car_ui_scroll_bar"> <!-- View height is dynamically calculated during layout. --> <View android:id="@+id/car_ui_scrollbar_thumb" android:layout_width="6dp" android:layout_height="20dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:background="@drawable/car_ui_recyclerview_scrollbar_thumb"/> <View android:id="@+id/car_ui_scrollbar_track" android:layout_width="10dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:layout_centerHorizontal="true" android:layout_above="@+id/car_ui_scrollbar_page_up"/> <View android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:background="#323232" android:layout_toLeftOf="@+id/car_ui_scrollbar_thumb" android:layout_above="@+id/car_ui_scrollbar_page_up" android:layout_marginRight="5dp"/> <View android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:background="#323232" android:layout_toRightOf="@+id/car_ui_scrollbar_thumb" android:layout_above="@+id/car_ui_scrollbar_page_up" android:layout_marginLeft="5dp"/> <ImageView android:id="@+id/car_ui_scrollbar_page_up" android:layout_width="75dp" android:layout_height="75dp" android:focusable="false" android:hapticFeedbackEnabled="false" android:src="@drawable/car_ui_recyclerview_ic_up" android:scaleType="centerInside" android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_centerHorizontal="true" android:layout_above="@+id/car_ui_scrollbar_page_down"/> <ImageView android:id="@+id/car_ui_scrollbar_page_down" android:layout_width="75dp" android:layout_height="75dp" android:focusable="false" android:hapticFeedbackEnabled="false" android:src="@drawable/car_ui_recyclerview_ic_down" android:scaleType="centerInside" android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true"/> </RelativeLayout>
Aby nakładać plik układu, musisz dodać wszystkie identyfikatory i przestrzeń nazw wartość atrybutu
overlay.xml
RRO. Zobacz pliki poniżej.res/xml/sample_overlay.xml
<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="drawable/car_ui_recyclerview_ic_down" value="@drawable/car_ui_recyclerview_ic_down"/> <item target="drawable/car_ui_recyclerview_ic_up" value="@drawable/car_ui_recyclerview_ic_up"/> <item target="drawable/car_ui_recyclerview_scrollbar_thumb" value="@drawable/car_ui_recyclerview_scrollbar_thumb"/> <item target="id/car_ui_scroll_bar" value="@id/car_ui_scroll_bar"/> <item target="id/car_ui_scrollbar_thumb" value="@id/car_ui_scrollbar_thumb"/> <item target="id/car_ui_scrollbar_track" value="@id/car_ui_scrollbar_track"/> <item target="id/car_ui_scrollbar_page_up" value="@id/car_ui_scrollbar_page_up"/> <item target="id/car_ui_scrollbar_page_down" value="@id/car_ui_scrollbar_page_down"/> <item target="layout/car_ui_recyclerview_scrollbar" value="@layout/car_ui_recyclerview_scrollbar"/> </overlay>
res/drawable/car_ui_recyclerview_ic_up.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,30.83L24,21.66l9.17,9.17L36,28 24,16 12,28z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_ic_down.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,16.42L24,25.59l9.17,-9.17L36,19.25l-12,12 -12,-12z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#0000FF" /> <corners android:radius="100dp"/> </shape>
Zalecamy sprawdzenie, jak współdziałają te pliki.
Dla uproszczenia wymiary i kolory są zakodowane na stałe. Najlepiej jednak praktyką jest zadeklarowanie tych wartości w polach
dimens.xml
icolors.xml
lub nawet oznaczonych jako pliki koloru w folderzeres/color/
. Aby dowiedzieć się więcej, zobacz Styl kodu Java AOSP dla współtwórców.Skompiluj i zainstaluj aplikację tak jak poprzednio. Udało Ci się zbudować aplikację
CarUiRecyclerView
z niebieskim paskiem przewijania i szarymi szynami.
Gratulacje! Obie strzałki pojawiają się u dołu paska przewijania.
udało się zastosować RRO do pliku zasobów układu car-ui-lib
za pomocą kompilacji Gradle
za pomocą Android Studio.
![CarUiRecyclerView z niebieskim paskiem przewijania i szarymi szynami](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=pl)
Pozycje listy RRO
Czas trwania: 15 minut
Do tej pory zastosowaliśmy RRO do car-ui-lib
komponentów za pomocą platformy
komponentów (nie AndroidX). Aby w ARRO używać komponentów AndroidaX, musisz dodać
zależności tego komponentu zarówno od aplikacji, jak i do RRO build.gradle.
należy też dodać do komponentu attrs
tego komponentu do elementu overlayable.xml
w swojej aplikacji,
jako sample_overlay.xml
w RRO.
Nasza biblioteka (car-ui-lib
) używa ConstraintLayout
i innych AndroidaX
komponentów, więc jego overlayable.xml
może wyglądać tak:
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<overlayable name="car-ui-lib">
…
<item type="attr" name="layout_constraintBottom_toBottomOf"/>
<item type="attr" name="layout_constraintBottom_toTopOf"/>
<item type="attr" name="layout_constraintCircle"/>
<item type="attr" name="layout_constraintCircleAngle"/>
<item type="attr" name="layout_constraintCircleRadius"/>
<item type="attr" name="layout_constraintDimensionRatio"/>
<item type="attr" name="layout_constraintEnd_toEndOf"/>
<item type="attr" name="layout_constraintEnd_toStartOf"/>
<item type="attr" name="layout_constraintGuide_begin"/>
<item type="attr" name="layout_constraintGuide_end"/>
<item type="attr" name="layout_constraintGuide_percent"/>
<item type="attr" name="layout_constraintHeight_default"/>
<item type="attr" name="layout_constraintHeight_max"/>
<item type="attr" name="layout_constraintHeight_min"/>
<item type="attr" name="layout_constraintHeight_percent"/>
<item type="attr" name="layout_constraintHorizontal_bias"/>
<item type="attr" name="layout_constraintHorizontal_chainStyle"/>
<item type="attr" name="layout_constraintHorizontal_weight"/>
<item type="attr" name="layout_constraintLeft_creator"/>
<item type="attr" name="layout_constraintLeft_toLeftOf"/>
<item type="attr" name="layout_constraintLeft_toRightOf"/>
<item type="attr" name="layout_constraintRight_creator"/>
<item type="attr" name="layout_constraintRight_toLeftOf"/>
<item type="attr" name="layout_constraintRight_toRightOf"/>
<item type="attr" name="layout_constraintStart_toEndOf"/>
<item type="attr" name="layout_constraintStart_toStartOf"/>
<item type="attr" name="layout_constraintTag"/>
<item type="attr" name="layout_constraintTop_creator"/>
<item type="attr" name="layout_constraintTop_toBottomOf"/>
<item type="attr" name="layout_constraintTop_toTopOf"/>
<item type="attr" name="layout_constraintVertical_bias"/>
<item type="attr" name="layout_constraintVertical_chainStyle"/>
…
</overlayable>
</resources>
Zmień układ elementów listy w
CarUiRecyclerView
za pomocąConstraintLayout
Dodaj lub zmodyfikuj te pliki w RRO:res/xml/sample_overlay.xml
<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="id/car_ui_list_item_touch_interceptor" value="@id/car_ui_list_item_touch_interceptor"/> <item target="id/car_ui_list_item_reduced_touch_interceptor" value="@id/car_ui_list_item_reduced_touch_interceptor"/> <item target="id/car_ui_list_item_start_guideline" value="@id/car_ui_list_item_start_guideline"/> <item target="id/car_ui_list_item_icon_container" value="@id/car_ui_list_item_icon_container"/> <item target="id/car_ui_list_item_icon" value="@id/car_ui_list_item_icon"/> <item target="id/car_ui_list_item_content_icon" value="@id/car_ui_list_item_content_icon"/> <item target="id/car_ui_list_item_avatar_icon" value="@id/car_ui_list_item_avatar_icon"/> <item target="id/car_ui_list_item_title" value="@id/car_ui_list_item_title"/> <item target="id/car_ui_list_item_body" value="@id/car_ui_list_item_body"/> <item target="id/car_ui_list_item_action_container_touch_interceptor" value="@id/car_ui_list_item_action_container_touch_interceptor"/> <item target="id/car_ui_list_item_action_container" value="@id/car_ui_list_item_action_container"/> <item target="id/car_ui_list_item_action_divider" value="@id/car_ui_list_item_action_divider"/> <item target="id/car_ui_list_item_switch_widget" value="@id/car_ui_list_item_switch_widget"/> <item target="id/car_ui_list_item_checkbox_widget" value="@id/car_ui_list_item_checkbox_widget"/> <item target="id/car_ui_list_item_radio_button_widget" value="@id/car_ui_list_item_radio_button_widget"/> <item target="id/car_ui_list_item_supplemental_icon" value="@id/car_ui_list_item_supplemental_icon"/> <item target="id/car_ui_list_item_end_guideline" value="@id/car_ui_list_item_end_guideline"/> <item target="attr/layout_constraintBottom_toBottomOf" value="@attr/layout_constraintBottom_toBottomOf"/> <item target="attr/layout_constraintBottom_toTopOf" value="@attr/layout_constraintBottom_toTopOf"/> <item target="attr/layout_constraintEnd_toEndOf" value="@attr/layout_constraintEnd_toEndOf"/> <item target="attr/layout_constraintEnd_toStartOf" value="@attr/layout_constraintEnd_toStartOf"/> <item target="attr/layout_constraintGuide_begin" value="@attr/layout_constraintGuide_begin"/> <item target="attr/layout_constraintGuide_end" value="@attr/layout_constraintGuide_end"/> <item target="attr/layout_constraintHorizontal_bias" value="@attr/layout_constraintHorizontal_bias"/> <item target="attr/layout_constraintLeft_toLeftOf" value="@attr/layout_constraintLeft_toLeftOf"/> <item target="attr/layout_constraintLeft_toRightOf" value="@attr/layout_constraintLeft_toRightOf"/> <item target="attr/layout_constraintRight_toLeftOf" value="@attr/layout_constraintRight_toLeftOf"/> <item target="attr/layout_constraintRight_toRightOf" value="@attr/layout_constraintRight_toRightOf"/> <item target="attr/layout_constraintStart_toEndOf" value="@attr/layout_constraintStart_toEndOf"/> <item target="attr/layout_constraintStart_toStartOf" value="@attr/layout_constraintStart_toStartOf"/> <item target="attr/layout_constraintTop_toBottomOf" value="@attr/layout_constraintTop_toBottomOf"/> <item target="attr/layout_constraintTop_toTopOf" value="@attr/layout_constraintTop_toTopOf"/> <item target="attr/layout_goneMarginBottom" value="@attr/layout_goneMarginBottom"/> <item target="attr/layout_goneMarginEnd" value="@attr/layout_goneMarginEnd"/> <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginLeft"/> <item target="attr/layout_goneMarginRight" value="@attr/layout_goneMarginRight"/> <item target="attr/layout_goneMarginStart" value="@attr/layout_goneMarginStart"/> <item target="attr/layout_goneMarginTop" value="@attr/layout_goneMarginTop"/> <item target="attr/layout_constraintVertical_chainStyle" value="@attr/layout_constraintVertical_chainStyle"/> <item target="layout/car_ui_list_item" value="@layout/car_ui_list_item"/> </overlay>
res/layout/car_ui_list_item.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:tag="carUiListItem" android:minHeight="@dimen/car_ui_list_item_height"> <!-- The following touch interceptor views are sized to encompass the specific sub-sections of the list item view to easily control the bounds of a background ripple effects. --> <com.android.car.ui.SecureView android:id="@+id/car_ui_list_item_touch_interceptor" android:layout_width="0dp" android:layout_height="0dp" android:background="@drawable/car_ui_list_item_background" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <!-- This touch interceptor does not include the action container --> <com.android.car.ui.SecureView android:id="@+id/car_ui_list_item_reduced_touch_interceptor" android:layout_width="0dp" android:layout_height="0dp" android:background="@drawable/car_ui_list_item_background" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/car_ui_list_item_action_container" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/car_ui_list_item_start_guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="@dimen/car_ui_list_item_start_inset" /> <FrameLayout android:id="@+id/car_ui_list_item_icon_container" android:layout_width="@dimen/car_ui_list_item_icon_container_width" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="@+id/car_ui_list_item_start_guideline" app:layout_constraintTop_toTopOf="parent"> <ImageView android:id="@+id/car_ui_list_item_icon" android:layout_width="@dimen/car_ui_list_item_icon_size" android:layout_height="@dimen/car_ui_list_item_icon_size" android:layout_gravity="center" android:visibility="gone" android:scaleType="fitCenter" /> <ImageView android:id="@+id/car_ui_list_item_content_icon" android:layout_width="@dimen/car_ui_list_item_content_icon_width" android:layout_height="@dimen/car_ui_list_item_content_icon_height" android:layout_gravity="center" android:visibility="gone" android:scaleType="fitCenter" /> <ImageView android:id="@+id/car_ui_list_item_avatar_icon" android:background="@drawable/car_ui_list_item_avatar_icon_outline" android:layout_width="@dimen/car_ui_list_item_avatar_icon_width" android:layout_height="@dimen/car_ui_list_item_avatar_icon_height" android:layout_gravity="center" android:visibility="gone" android:scaleType="fitCenter" /> </FrameLayout> <CarUiTextView android:id="@+id/car_ui_list_item_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin" android:singleLine="@bool/car_ui_list_item_single_line_title" android:textAppearance="@style/TextAppearance.CarUi.ListItem" android:layout_gravity="right" android:gravity="right" android:textAlignment="viewEnd" app:layout_constraintBottom_toTopOf="@+id/car_ui_list_item_body" app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container" app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="packed" app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" /> <CarUiTextView android:id="@+id/car_ui_list_item_body" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin" android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body" android:layout_gravity="right" android:gravity="right" android:textAlignment="viewEnd" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container" app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container" app:layout_constraintTop_toBottomOf="@+id/car_ui_list_item_title" app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" /> <!-- This touch interceptor is sized and positioned to encompass the action container --> <com.android.car.ui.SecureView android:id="@+id/car_ui_list_item_action_container_touch_interceptor" android:layout_width="0dp" android:layout_height="0dp" android:background="@drawable/car_ui_list_item_background" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@id/car_ui_list_item_action_container" app:layout_constraintEnd_toEndOf="@id/car_ui_list_item_action_container" app:layout_constraintStart_toStartOf="@id/car_ui_list_item_action_container" app:layout_constraintTop_toTopOf="@id/car_ui_list_item_action_container" /> <FrameLayout android:id="@+id/car_ui_list_item_action_container" android:layout_width="wrap_content" android:minWidth="@dimen/car_ui_list_item_icon_container_width" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/car_ui_list_item_end_guideline" app:layout_constraintTop_toTopOf="parent"> <View android:id="@+id/car_ui_list_item_action_divider" android:layout_width="@dimen/car_ui_list_item_action_divider_width" android:layout_height="@dimen/car_ui_list_item_action_divider_height" android:layout_gravity="start|center_vertical" android:background="@drawable/car_ui_list_item_divider" /> <Switch android:id="@+id/car_ui_list_item_switch_widget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="false" android:focusable="false" /> <CheckBox android:id="@+id/car_ui_list_item_checkbox_widget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="false" android:focusable="false" /> <RadioButton android:id="@+id/car_ui_list_item_radio_button_widget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="false" android:focusable="false" /> <ImageView android:id="@+id/car_ui_list_item_supplemental_icon" android:layout_width="@dimen/car_ui_list_item_supplemental_icon_size" android:layout_height="@dimen/car_ui_list_item_supplemental_icon_size" android:layout_gravity="center" android:scaleType="fitCenter" /> </FrameLayout> <androidx.constraintlayout.widget.Guideline android:id="@+id/car_ui_list_item_end_guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_end="@dimen/car_ui_list_item_end_inset" /> </androidx.constraintlayout.widget.ConstraintLayout>
car_ui_list_item.xml
odwołuje się do kilku elementów, które odwołują się do kilku komponentów/ zasobów, które nie są uwzględnione jako zależności aplikacji. Otocar-ui-lib
zasoby. Możesz to naprawić, dodając użytkownikacar-ui-lib
jako zależność od aplikacji RRO wapp/build.gradle
:dependencies { implementation 'com.android.car.ui:car-ui-lib:2.0.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.4.0' }
Tytuł i treść są teraz wyrównane do prawej, a nie do lewej.
![Tytuł i treść wyrównane do prawej](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=pl)
Do aplikacji car-ui-lib
zastosowaliśmy RRO tylko przy użyciu komponentów AndroidaX
(ConstraintLayout
), gdy jego atrybuty znajdowały się w car-ui-lib
o nazwie overlayable.xml
oraz RRO sample_overlay.xml
. Jest
zrobić coś podobnego we własnej aplikacji. Wystarczy dodać wszystkie
attrs
w stosunku do wskaźników overlayable.xml
Twojej aplikacji, podobnie jak w przypadku car-ui-lib
.
Nie można jednak wykonać takiej operacji w przypadku aplikacji, która korzysta z komponentów Androida X,
aplikacja car-ui-lib
jest uzależniona od build.gradle
(gdy aplikacja korzysta
car-ui-lib
komponentów). Ponieważ mapowania atrybutów zostały już zdefiniowane w
overlayable.xml
z biblioteki car-ui-lib
, dodaję je do
overlayable.xml
aplikacji z zależnością car-ui-lib
spowodowałby
mergeDebugResources
podobny błąd poniżej. To dlatego, że te atrybuty
znajdują się w kilku plikach overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'