Verwenden Sie die car-ui-lib
-Bibliothek, um konsistente Infotainmentsysteme (In-Vehicle Infotainment, IVI) zu starten. In diesem Codelab lernen Sie car-ui-lib
kennen und erfahren, wie Sie mithilfe von Laufzeitressourcen-Overlays (RROs) Komponenten in der Bibliothek anpassen können.
Lerninhalte
Anleitung:
- Fügen Sie Ihrer Android-App
car-ui-lib
-Komponenten hinzu. - Verwenden Sie Gradle, um Android-Apps und RROs zu erstellen.
- Verwenden Sie RROs mit
car-ui-lib
.
In diesem Codelab wird nicht detailliert beschrieben, wie RROs funktionieren. Weitere Informationen finden Sie unter Wert der Ressourcen einer App zur Laufzeit ändern und Fehlerbehebung bei Laufzeit-Ressourcenüberlagerungen.
Vorbereitung
Voraussetzungen
Bevor Sie beginnen, benötigen Sie Folgendes:
Computer mit Befehlszeile (Linux-, Mac- oder Windows-Computer mit Windows-Subsystem für Linux)
Ein Android-Gerät oder Emulator, das bzw. der mit Ihrem Computer verbunden ist. Weitere Informationen finden Sie unter Android-Quellcode herunterladen und Android erstellen.
Grundkenntnisse zu RROs
Neue Android-App erstellen
Dauer:15 Minuten
In diesem Abschnitt erstellen Sie ein neues Android Studio-Projekt.
Erstellen Sie in Android Studio eine App mit einem
EmptyActivity
.Abbildung 1: Leere Aktivität erstellen Benennen Sie die App
CarUiCodelab
und wählen Sie die Sprache Java aus. Optional können Sie auch einen Speicherort für die Datei auswählen. Akzeptieren Sie für die restlichen Einstellungen die Standardwerte.Abbildung 2. Geben Sie einen Namen für Ihre App ein. Ersetzen Sie
activity_main.xml
durch den folgenden Codeblock:<?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>
In diesem Codeblock wird der nicht definierte String
sample_text
angezeigt.Fügen Sie den
sample_text
-Ressourcenstring hinzu und setzen Sie ihn in der Dateistrings.xml
auf „Hallo Welt!“. Wählen Sie zum Öffnen dieser Datei app > src > main > res > values > strings.xml aus.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
Klicken Sie rechts oben auf die grüne Schaltfläche Abspielen, um Ihre App zu erstellen. Dadurch wird die APK automatisch über Gradle auf Ihrem Emulator oder Android-Gerät installiert.
Die neue App sollte automatisch auf Ihrem Emulator oder Android-Gerät geöffnet werden. Andernfalls öffnen Sie die CarUiCodelab
App über den App Launcher, der jetzt installiert ist.
Sie sieht so aus:

car-ui-lib zu Ihrer Android-App hinzufügen
Dauer:15 Minuten
Fügen Sie Ihrer App car-ui-lib
hinzu:
Wenn Sie der Datei
build.gradle
Ihres Projekts die Abhängigkeitcar-ui-lib
hinzufügen möchten, wählen Sie app > build.gradle aus. Ihre Abhängigkeiten sollten so aussehen: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' }
car-ui-lib-Komponenten in Ihrer Android-App verwenden
Jetzt, da Sie car-ui-lib
haben, fügen Sie Ihrer App eine Symbolleiste hinzu.
Überschreiben Sie in der Datei
MainActivity.java
die MethodeonCreate
:@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); }
Achten Sie darauf,
ToolbarController
zu importieren:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Wenn Sie das
Theme.CarUi.WithToolbar
-Design verwenden möchten, wählen Sie app > src > main > AndroidManifest.xml aus und aktualisieren SieAndroidManifest.xml
so, dass er so aussieht:<?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>
Drücken Sie wie zuvor auf die grüne Schaltfläche Wiedergabe, um die App zu erstellen.
Ihrer App RROs hinzufügen
Dauer: 30 Minuten
Wenn Sie mit RROs vertraut sind, fahren Sie mit dem nächsten Abschnitt Ihrer App einen Berechtigungscontroller hinzufügen fort. Andernfalls finden Sie die Grundlagen von RROs unter Wert der Ressourcen einer App zur Laufzeit ändern.
Ihrer App einen Berechtigungscontroller hinzufügen
Wenn Sie steuern möchten, welche Ressourcen ein RRO-Paket überlagert, fügen Sie dem Ordner /res
Ihrer App eine Datei mit dem Namen overlayable.xml
hinzu. Diese Datei dient als Berechtigungscontroller zwischen Ihrer App (dem Ziel) und Ihrem RRO-Paket (dem Overlay).
Fügen Sie Ihrer App
res/values/overlayable.xml
hinzu und kopieren Sie den folgenden Inhalt in die Datei:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Da der String
sample_text
von einer RRO überlagert werden muss, fügen Sie den Ressourcennamen in „overlayable.xml“ der App ein.Die Datei
overlayable.xml
MUSS sich inres/values/
befinden. Andernfalls kann dieOverlayManagerService
sie nicht finden.Weitere Informationen zu überlagerbaren Ressourcen und ihrer Konfiguration finden Sie unter Überlagerbare Ressourcen einschränken.
RRO-Paket erstellen
In diesem Abschnitt erstellen Sie ein RRO-Paket, um den oben angezeigten String von „Hello World!“ in „Hello World RRO“ zu ändern.
Wenn Sie ein neues Projekt erstellen möchten, wählen Sie Datei > Neu > Neues Projekt aus. Wählen Sie Keine Aktivität anstelle von „Leere Aktivität“ aus, da RRO-Pakete nur Ressourcen enthalten.
Ihre Konfigurationen sollten in etwa so aussehen wie unten dargestellt. Der Speicherort kann variieren:
Nachdem Sie das neue
CarUiRRO
-Projekt erstellt haben, deklarieren Sie es als RRO, indem SieAndroidManifest.xml
ändern.<?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>
Dadurch wird ein Fehler mit
@xml/sample_overlay
ausgegeben. In der DateiresourcesMap
werden Ressourcennamen aus dem Zielpaket dem RRO-Paket zugeordnet. Für RRO-Pakete ist es obligatorisch, das FlaghasCode
auffalse
zu setzen. Außerdem dürfen RRO-Pakete keine DEX-Dateien enthalten.Kopieren Sie den folgenden Codeblock in
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
sample_text
zu…/res/values/strings.xml
hinzufügen:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
Um das RRO-Ziel zu erstellen, klicken Sie auf die grüne Schaltfläche Wiedergabe, um einen Gradle-Build Ihrer RRO auf Ihrem Emulator oder Android-Gerät zu erstellen.
Führen Sie folgenden Befehl aus, um zu prüfen, ob die RRO richtig installiert ist:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Mit diesem Befehl werden nützliche Informationen zum Status der RRO-Pakete im System angezeigt.
[ ]
gibt an, dass die RRO installiert und zur Aktivierung bereit ist.---
gibt an, dass die RRO installiert ist, aber Fehler enthält.[X]
bedeutet, dass die RRO installiert und aktiviert ist.
Wenn Ihre Laufzeitressourcen-Overlays Fehler enthalten, lesen Sie den Hilfeartikel Fehlerbehebung bei Laufzeitressourcen-Overlays, bevor Sie fortfahren.
So aktivieren Sie die RRO und prüfen, ob sie aktiviert ist:
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
Ihre App zeigt den String „Hello World RRO“ an.

Glückwunsch! Sie haben Ihre erste RRO erstellt.
Wenn Sie RROs verwenden, können Sie die Flags --no-resource-deduping
und --no-resource-removal
des Android Asset Packaging Tools (AAPT2) verwenden, die unter Link-Optionen beschrieben werden.
Sie müssen die Flags in diesem Codelab nicht hinzufügen. Wir empfehlen Ihnen jedoch, sie in Ihren RROs zu verwenden, um das Entfernen von Ressourcen und Probleme beim Debuggen zu vermeiden. Sie können sie der build.gradle
-Datei Ihrer RRO so hinzufügen:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Weitere Informationen zu diesen Flags finden Sie unter Paket erstellen und AAPT2.
car-ui-lib
-Komponenten in Ihrer Android-App mit RROs ändern
Auf dieser Seite wird beschrieben, wie Sie mit einem Laufzeit-Ressourcen-Overlay (RRO) Komponenten aus der car-ui-lib
-Bibliothek in Ihrer Android-App ändern können.
Hintergrundfarbe der Symbolleiste festlegen
Dauer:15 Minuten
So ändern Sie die Hintergrundfarbe der Symbolleiste:
Fügen Sie Ihrer RRO-App den folgenden Wert hinzu und legen Sie die Ressource auf knallgrün (
#0F0
) fest:<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
Die
car-ui-lib
-Bibliothek enthält eine Ressource namenscar_ui_toolbar_background
. Wenn diese Ressource in der Konfiguration einer RRO enthalten ist, ändert sich die Symbolleiste nicht, da der falsche Wert als Ziel festgelegt ist.Aktualisieren Sie in der
AndroidManifest.xml
für Ihre RRO den Wert fürtargetName
so, dass er aufcar-ui-lib
verweist:… android:targetName="car-ui-lib" …
Sie MÜSSEN für jedes Zielpaket, das Sie mit der Funktion „RRO“ bearbeiten möchten, ein neues RRO-Paket erstellen. Wenn Sie beispielsweise Overlays für zwei verschiedene Ziele erstellen, müssen Sie zwei Overlay-APKs erstellen.
Erstellen, prüfen, installieren und aktivieren Sie die RRO wie zuvor.
Ihre App wird so angezeigt:

Layouts und Stile für responsive Suchanzeigen
Dauer:15 Minuten
In dieser Übung erstellen Sie eine neue App, die der App ähnelt, die Sie zuvor erstellt haben. Mit dieser App kann das Layout überlagert werden. Folgen Sie denselben Schritten wie zuvor oder ändern Sie Ihre vorhandene App.
Fügen Sie
overlayable.xml
die folgenden Zeilen hinzu:<?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>
activity_main.xml
sollte so angezeigt werden:<?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>
Erstellen Sie in Ihrer RRO-App eine
res/layout/activity_main.xml
und fügen Sie Folgendes hinzu:<?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>
Aktualisieren Sie
res/values/styles.xml
, um dem RRO unseren Stil hinzuzufügen:<?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>
Ändern Sie
targetName
inAndroidManifest.xml
, sodass es auf den Namen Ihrer neuen App verweist:… android:targetName="CarUiCodelab" …
Fügen Sie die Ressourcen der
sample_overlay.xml
-Datei in Ihrer RRO hinzu:<?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>
Erstellen und installieren Sie die App und die RRO wie zuvor (grüne Schaltfläche Wiedergabe). Achten Sie darauf, dass Ihre RRO aktiviert ist.
Die App und die RRO werden so gerendert: Der RRO-Text „Hallo Welt“ ist grün und wie im Layout-RRO angegeben zentriert.

CarUiRecyclerView zur App hinzufügen
Dauer:15 Minuten
Die CarUiRecyclerView
-Schnittstelle bietet APIs für den Zugriff auf eine RecyclerView
, die über car-ui-lib
-Ressourcen angepasst wird. Beispielsweise prüft CarUiRecyclerView
bei der Laufzeit ein Flag, um festzustellen, ob die Bildlaufleiste aktiviert werden soll oder nicht, und wählt das entsprechende Layout aus.

Wenn Sie
CarUiRecyclerView
hinzufügen möchten, fügen Sie ihn den Dateienactivity_main.xml
undMainActivity.java
hinzu. Sie können entweder eine neue App von Grund auf neu erstellen oder die vorhandene App ändern. Wenn Sie die vorhandene App ändern, entfernen Sie unbedingt nicht deklarierte Ressourcen ausoverlayable.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"/>
Möglicherweise wird der folgende Fehler angezeigt, den Sie ignorieren können:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Solange die Schreibweise Ihrer Klasse korrekt ist und Sie
car-ui-lib
als Abhängigkeit hinzugefügt haben, können Sie Ihre APK erstellen und kompilieren. Wählen Sie Datei > Caches ungültig machen aus und klicken Sie dann auf Ungültig machen und neu starten, um den Fehler zu beheben.Fügen Sie
MainActivity.java
Folgendes hinzu:package 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; }
Erstellen und installieren Sie Ihre App wie gewohnt.
Sie sehen jetzt ein CarUiRecyclerView
:

Bildlaufleiste mit einem RRO entfernen
Dauer:10 Minuten
In dieser Übung erfahren Sie, wie Sie mithilfe eines RRO die Bildlaufleiste aus CarUiRecyclerView
entfernen.
Fügen Sie in Ihrer RRO die folgenden Dateien hinzu und ändern Sie sie:
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>
Die Ressource
car_ui_scrollbar_enable
ist eine booleschecar-ui-lib
-Ressource, mit der gesteuert wird, ob die für Mobilgeräte optimierte Bildlaufleiste mit den Schaltflächen „Nach oben“ und „Nach unten“ inCarUiRecyclerView
vorhanden ist oder nicht. Wennfalse
festgelegt ist, wirkt sichCarUiRecyclerView
wie eine AndroidX-RecyclerView
aus.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>
Erstellen und installieren Sie Ihre App wie gewohnt. Die Bildlaufleiste wurde aus CarUiRecyclerView
entfernt:

Layout verwenden, um die Bildlaufleiste von CarUiRecyclerView zu überlagern
Dauer:15 Minuten
In dieser Übung ändern Sie das Layout der CarUiRecyclerView
-Bildlaufleiste.
Fügen Sie die folgenden Dateien in Ihrer RRO-App hinzu und ändern Sie sie.
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>
Wenn Sie eine Layoutdatei überlagern möchten, müssen Sie der
overlay.xml
Ihrer RRO alle IDs und Namespaceattribute hinzufügen. Siehe die Dateien unten.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>
Es wird empfohlen, die Interaktion dieser Dateien zu prüfen.
Zur Vereinfachung sind Dimensionen und Farben hartcodiert. Es wird jedoch empfohlen, diese Werte in
dimens.xml
undcolors.xml
anzugeben oder sie sogar als Farbdateien im Ordnerres/color/
zu bezeichnen. Weitere Informationen finden Sie unter AOSP Java-Codestil für Mitwirkende.Erstellen und installieren Sie Ihre App wie gewohnt. Sie haben
CarUiRecyclerView
mit einer blauen Bildlaufleiste und grauen Rändern erstellt.
Glückwunsch! Beide Pfeile werden unten in der Bildlaufleiste angezeigt. Sie haben eine RRO mit dem Gradle-Build-System über Android Studio auf eine car-ui-lib
-Layout-Ressourcendatei angewendet.

RRO-Listenelemente
Dauer:15 Minuten
Bisher haben Sie eine RRO auf car-ui-lib
-Komponenten mit Framework-Komponenten (nicht AndroidX) angewendet. Wenn Sie AndroidX-Komponenten in einer RRO verwenden möchten, müssen Sie die Abhängigkeiten dieser Komponente sowohl der App als auch der RRO hinzufügen. build.gradle.
Sie müssen auch die attrs
dieser Komponente zu overlayable.xml
in Ihrer App und zur sample_overlay.xml
in Ihrer RRO hinzufügen.
Unsere Bibliothek (car-ui-lib
) verwendet ConstraintLayout
sowie andere AndroidX-Komponenten. Die overlayable.xml
könnte also so aussehen:
<?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>
Ändern Sie das Layout der Listenelemente in der
CarUiRecyclerView
mithilfe vonConstraintLayout
. Fügen Sie die folgenden Dateien in Ihre RRO hinzu oder ändern Sie sie: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
verweist auf mehrere Komponenten/Ressourcen, die nicht als Abhängigkeiten der App enthalten sind. Das sindcar-ui-lib
-Ressourcen. Sie können das Problem beheben, indem Siecar-ui-lib
inapp/build.gradle
als Abhängigkeit Ihrer RRO-App hinzufügen: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' }
Der Titel und der Text sind jetzt rechtsbündig statt linksbündig ausgerichtet.

Wir haben eine RRO nur dann auf car-ui-lib
mit AndroidX-Komponenten (ConstraintLayout
) angewendet, wenn ihre Attribute sowohl in der car-ui-lib
-Datei mit dem Namen overlayable.xml
als auch in der RRO sample_overlay.xml
vorhanden waren. In Ihrer eigenen App ist etwas Ähnliches möglich. Fügen Sie einfach alle entsprechenden attrs
zur overlayable.xml
Ihrer App hinzu, ähnlich wie bei car-ui-lib
.
Es ist jedoch nicht möglich, eine App mit AndroidX-Komponenten per RRO zu installieren, wenn die App car-ui-lib
als Abhängigkeit in ihrer build.gradle
hat (wenn die App car-ui-lib
-Komponenten verwendet). Da die Attributzuordnungen bereits in der overlayable.xml
der car-ui-lib
-Bibliothek definiert waren, würde das Hinzufügen der Attributzuordnungen zur overlayable.xml
Ihrer App mit car-ui-lib
als Abhängigkeit zu einem mergeDebugResources
-Fehler wie dem unten stehenden führen. Das liegt daran, dass diese Attribute in mehreren overlayable.xml
-Dateien vorhanden sind:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'