Verwenden Sie die Bibliothek car-ui-lib
um selbstkonsistente fahrzeuginterne Infotainmentsysteme (IVI) zu starten. Dieses Codelab führt Sie in car-ui-lib
ein und zeigt Ihnen, wie Sie Runtime Resource Overlays (RROs) verwenden können, um Komponenten in der Bibliothek anzupassen.
Was Sie lernen werden
Wie man:
- Integrieren Sie
car-ui-lib
Komponenten in Ihre Android-App. - 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 „Ändern des Werts der Ressourcen einer App zur Laufzeit“ und „Fehlerbehebung bei Laufzeitressourcenüberlagerungen“ .
Bevor du anfängst
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Sie Folgendes haben:
Computer mit Befehlszeile (Linux-Maschine, Mac oder Windows-Maschine mit Windows-Subsystem für Linux).
Mit Ihrem Gerät verbundenes Android-Gerät oder Emulator. Siehe „Herunterladen der Android-Quelle“ und „Android erstellen“ .
Grundkenntnisse über RROs.
Erstellen Sie eine neue Android-App
Dauer: 15 Minuten
In diesem Abschnitt erstellen Sie ein neues Android Studio-Projekt.
Erstellen Sie in Android Studio eine App mit einer
EmptyActivity
.Benennen Sie die App
CarUiCodelab
und wählen Sie dann die Java-Sprache aus. Bei Bedarf können Sie auch einen Dateispeicherort auswählen. Übernehmen Sie die Standardwerte für die übrigen Einstellungen.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>
Dieser Codeblock zeigt die Zeichenfolge
sample_text
an, die nicht definiert ist.Fügen Sie die Ressourcenzeichenfolge
sample_text
hinzu und legen Sie sie auf „Hello World!“ fest. in Ihrerstrings.xml
-Datei. Um diese Datei zu öffnen, wählen Sie app > src > main > res > value > 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>
Um Ihre App zu erstellen, klicken Sie oben rechts auf die grüne Play- Schaltfläche. 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. Wenn nicht, öffnen Sie die CarUiCodelab
App über den App-Launcher, der jetzt installiert ist. Es sieht so aus:
Fügen Sie car-ui-lib zu Ihrer Android-App hinzu
Dauer: 15 Minuten
Fügen Sie Ihrer App car-ui-lib
hinzu:
Um die
car-ui-lib
Abhängigkeit zurbuild.gradle
Datei Ihres Projekts hinzuzufügen, wählen Sie app > build.gradle aus. Ihre Abhängigkeiten sollten wie folgt 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' }
Verwenden Sie car-ui-lib-Komponenten in Ihrer Android-App
Nachdem Sie nun car-ui-lib
haben, fügen Sie Ihrer App eine Symbolleiste hinzu.
Überschreiben Sie in Ihrer
MainActivity.java
Datei dieonCreate
Methode:@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); }
Stellen Sie sicher, dass Sie
ToolbarController
importieren:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Um das
Theme.CarUi.WithToolbar
-Design zu verwenden, wählen Sie app > src > main > AndroidManifest.xml aus und aktualisieren Sie dannAndroidManifest.xml
so, dass es wie folgt 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>
Um die App zu erstellen, drücken Sie wie zuvor die grüne Play- Taste.
Fügen Sie Ihrer App RROs hinzu
Dauer: 30 Minuten
Wenn Sie mit RROs vertraut sind, fahren Sie mit dem nächsten Abschnitt fort: Hinzufügen eines Berechtigungscontrollers zu Ihrer App . Ansonsten erfahren Sie, wie Sie die Grundlagen von RROs erlernen: Ändern des Werts der Ressourcen einer App zur Laufzeit .
Fügen Sie Ihrer App einen Berechtigungscontroller hinzu
Um zu steuern, welche Ressourcen ein RRO-Paket überlagert, fügen Sie eine Datei mit dem Namen overlayable.xml
zum Ordner /res
Ihrer App hinzu. Diese Datei dient als Berechtigungscontroller zwischen Ihrer App (dem Ziel ) und Ihrem RRO-Paket (dem Overlay ).
Fügen Sie
res/values/overlayable.xml
zu Ihrer App hinzu und kopieren Sie den folgenden Inhalt in Ihre 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 die Zeichenfolge
sample_text
von einem RRO überlagerbar sein muss, fügen Sie den Ressourcennamen in die Datei „overlayable.xml“ der App ein.Ihre Datei
overlayable.xml
MUSS sich inres/values/
befinden. Wenn nicht, kann derOverlayManagerService
es nicht finden.Weitere Informationen zu überlagerbaren Ressourcen und deren Konfiguration finden Sie unter Überlagerbare Ressourcen einschränken .
Erstellen Sie ein RRO-Paket
In diesem Abschnitt erstellen Sie ein RRO-Paket, um die oben angezeigte Zeichenfolge von „Hello World!“ zu ändern. zu „Hallo Welt RRO“.
Um ein neues Projekt zu erstellen, wählen Sie Datei > Neu > Neues Projekt . Stellen Sie sicher, dass Sie „Keine Aktivität“ anstelle von „Leere Aktivität“ auswählen, da RRO-Pakete nur Ressourcen enthalten.
Ihre Konfigurationen ähneln den unten dargestellten. Der Speicherort kann unterschiedlich sein:
Nachdem Sie das neue
CarUiRRO
Projekt erstellt haben, deklarieren Sie das Projekt 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 entsteht ein Fehler mit
@xml/sample_overlay
. DieresourcesMap
Datei ordnet Ressourcennamen vom Zielpaket dem RRO-Paket zu.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>
Fügen Sie
sample_text
zu…/res/values/strings.xml
hinzu:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
Um Ihr RRO-Ziel zu erstellen, drücken Sie die grüne Play- Taste, um einen Gradle-Build Ihres RRO auf Ihrem Emulator oder Android-Gerät zu erstellen.
Führen Sie Folgendes aus, um zu überprüfen, ob Ihr RRO ordnungsgemäß installiert ist:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Dieser Befehl zeigt nützliche Informationen über den Status von RRO-Paketen auf dem System an.
-
[ ]
zeigt an, dass das RRO installiert und zur Aktivierung bereit ist. -
---
zeigt an, dass das RRO installiert ist, aber Fehler enthält. -
[X]
bedeutet, dass das RRO installiert und aktiviert ist.
Wenn Ihr RRO Fehler enthält, lesen Sie den Abschnitt Fehlerbehebung bei Laufzeitressourcen-Overlays, bevor Sie fortfahren.
-
So aktivieren Sie das RRO und überprüfen, ob es 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 die Zeichenfolge „Hello World RRO“ an.
Glückwunsch! Sie haben Ihr erstes RRO erstellt.
Wenn Sie RROs verwenden, möchten Sie möglicherweise die unter Link-Optionen beschriebenen Flags --no-resource-deduping
und --no-resource-removal
des Android Asset Packaging Tool (AAPT2) verwenden. Es ist nicht notwendig, die Flags in diesem Codelab hinzuzufügen, wir empfehlen Ihnen jedoch, sie in Ihren RROs zu verwenden, um das Entfernen von Ressourcen (und Debugging-Probleme) zu vermeiden. Sie können sie wie folgt zur build.gradle
Datei Ihres RRO hinzufügen:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Weitere Informationen zu diesen Flags finden Sie unter Erstellen des Pakets und AAPT2 .
Ändern Sie car-ui-lib
Komponenten mithilfe von RROs in Ihrer Android-App
Auf dieser Seite wird beschrieben, wie Sie ein Runtime Resource Overlay (RRO) verwenden können, um Komponenten aus der car-ui-lib
Bibliothek in Ihrer Android-App zu ändern.
Legen Sie die Hintergrundfarbe der Symbolleiste fest
Dauer: 15 Minuten
So ändern Sie die Hintergrundfarbe der Symbolleiste:
Fügen Sie Ihrer RRO-App den folgenden Wert hinzu und setzen Sie die Ressource auf Hellgrün (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
Die Bibliothek
car-ui-lib
enthält eine Ressource namenscar_ui_toolbar_background
. Wenn diese Ressource in der Konfiguration eines RRO enthalten ist, ändert sich die Symbolleiste nicht, da der falsche Wert als Ziel ausgewählt ist.Aktualisieren Sie in der
AndroidManifest.xml
für Ihr RROtargetName
so, dass es aufcar-ui-lib
verweist:… android:targetName="car-ui-lib" …
Sie MÜSSEN für jedes Zielpaket, für das Sie RRO erstellen 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, überprüfen, installieren und aktivieren Sie das RRO auf die gleiche Weise wie zuvor.
Ihre App sieht folgendermaßen aus:
RRO-Layouts und -Stile
Dauer: 15 Minuten
In dieser Übung erstellen Sie eine neue App, die der zuvor erstellten App ähnelt. Diese App ermöglicht die Überlagerung des Layouts. Befolgen Sie die gleichen Schritte wie zuvor oder ändern Sie Ihre vorhandene App.
Stellen Sie sicher, dass Sie die folgenden Zeilen zu
overlayable.xml
hinzufügen:<?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>
Stellen Sie sicher, dass
activity_main.xml
wie folgt aussieht:<?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 unseren Stil zum RRO 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 den
targetName
inAndroidManifest.xml
so, dass er auf den Namen Ihrer neuen App verweist:… android:targetName="CarUiCodelab" …
Fügen Sie die Ressourcen zur Datei
sample_overlay.xml
in Ihrem 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 RRO auf die gleiche Weise wie zuvor (grüne Play- Schaltfläche). Stellen Sie sicher, dass Sie Ihr RRO aktivieren.
Die App und RRO rendern wie folgt. Der „Hello World“-RRO-Text ist grün und wird gemäß der Layout-RRO-Angabe zentriert.
Fügen Sie CarUiRecyclerView zu Ihrer App hinzu
Dauer: 15 Minuten
Die CarUiRecyclerView
Schnittstelle stellt APIs für den Zugriff auf eine RecyclerView
bereit, die über car-ui-lib
Ressourcen angepasst wird. CarUiRecyclerView
überprüft beispielsweise zur Laufzeit ein Flag, um festzustellen, ob die Bildlaufleiste aktiviert werden soll oder nicht, und wählt das entsprechende Layout aus.
Um eine
CarUiRecyclerView
hinzuzufügen, fügen Sie sie Ihren Dateienactivity_main.xml
undMainActivity.java
hinzu. Sie können entweder eine neue App von Grund auf erstellen oder die vorhandene App ändern. Wenn Sie die vorhandene App ändern, müssen Sie nicht deklarierte Ressourcen ausoverlayable.xml
entfernen.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 erscheint der folgende Fehler, den Sie ignorieren können:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Solange Ihre Klasse richtig geschrieben ist und Sie
car-ui-lib
als Abhängigkeit hinzugefügt haben, können Sie Ihre APK erstellen und kompilieren. Um den Fehler zu beheben, wählen Sie „Datei“ > „Caches ungültig machen“ und klicken Sie dann auf „Ungültig machen und neu starten“.Fügen Sie Folgendes zu
MainActivity.java
hinzupackage 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 zuvor.
Sie sehen jetzt eine CarUiRecyclerView
:
Verwenden Sie ein RRO, um die Bildlaufleiste zu entfernen
Dauer: 10 Minuten
Diese Übung zeigt Ihnen, wie Sie mit einem RRO die Bildlaufleiste aus CarUiRecyclerView
entfernen.
Fügen Sie in Ihrem 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, die steuert, ob die für Autos optimierte Bildlaufleiste mit den Auf- und Ab-Schaltflächen inCarUiRecyclerView
vorhanden ist oder nicht. Wenn es auffalse
gesetzt ist, verhält sichCarUiRecyclerView
wie ein AndroidXRecyclerView
.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 zuvor. Die Bildlaufleiste wurde jetzt aus CarUiRecyclerView
entfernt:
Verwenden Sie ein Layout, 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>
Um eine Layoutdatei zu überlagern, müssen Sie alle IDs und Namespace-Attribute zur
overlay.xml
Ihres RRO 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 untersuchen.
Der Einfachheit halber sind Abmessungen und Farben fest codiert. Eine bewährte Vorgehensweise besteht jedoch darin, diese Werte in
dimens.xml
undcolors.xml
zu deklarieren oder sie sogar als Farbdateien im Ordnerres/color/
festzulegen. Weitere Informationen finden Sie unter AOSP Java-Codestil für Mitwirkende .Erstellen und installieren Sie Ihre App wie zuvor. Sie haben
CarUiRecyclerView
mit einer blauen Bildlaufleiste und grauen Schienen erstellt.
Glückwunsch! Beide Pfeile werden am unteren Rand der Bildlaufleiste angezeigt. Sie haben mit dem Gradle-Build-System über Android Studio erfolgreich ein RRO auf eine car-ui-lib
Layout-Ressourcendatei angewendet.
RRO-Listenelemente
Dauer: 15 Minuten
Bisher haben Sie mithilfe von Framework-Komponenten (nicht AndroidX) ein RRO auf car-ui-lib
Komponenten angewendet. Um AndroidX-Komponenten in einem RRO zu verwenden, müssen Sie die Abhängigkeiten dieser Komponente sowohl zur App als auch zum RRO build.gradle.
Sie müssen außerdem die attrs
dieser Komponente zu overlayable.xml
in Ihrer App sowie zu sample_overlay.xml
in Ihrem RRO hinzufügen.
Unsere Bibliothek ( car-ui-lib
) verwendet ConstraintLayout
sowie andere AndroidX-Komponenten, daher könnte ihre overlayable.xml
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
CarUiRecyclerView
mitConstraintLayout
. Fügen Sie die folgenden Dateien in Ihrem 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 Referenzen auf mehrere Komponenten/Ressourcen, die nicht als Abhängigkeiten der App enthalten sind. Dies sindcar-ui-lib
Ressourcen. Sie können dies beheben, indem Siecar-ui-lib
als Abhängigkeit zu Ihrer RRO-App inapp/build.gradle
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' }
Titel und Text sind jetzt rechtsbündig statt linksbündig ausgerichtet.
Wir haben nur dann ein RRO auf car-ui-lib
mithilfe von AndroidX-Komponenten ( ConstraintLayout
) angewendet, wenn dessen Attribute in der car-ui-lib
-Datei mit dem Namen overlayable.xml
sowie im RRO sample_overlay.xml
vorhanden waren. Es ist möglich, etwas Ähnliches in Ihrer eigenen App zu tun. 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 erstellen, wenn die App car-ui-lib
als Abhängigkeit in ihrem build.gradle
hat (wenn die App car-ui-lib
Komponenten verwendet). Da die Attributzuordnungen bereits in der Datei „ overlayable.xml
der Bibliothek car-ui-lib
definiert wurden, würde das Hinzufügen zur Datei overlayable.xml
Ihrer App mit car-ui-lib
als Abhängigkeit zu einem mergeDebugResources
Fehler wie dem folgenden führen. Dies liegt daran, dass diese Attribute in mehreren overlayable.xml
Dateien vorhanden sind:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'