Utilisez la bibliothèque car-ui-lib
pour lancer des systèmes d'infodivertissement (IVI) intégrés au véhicule et cohérents. Cet atelier de programmation vous présente car-ui-lib
et explique comment utiliser des superpositions de ressources d'exécution (RRO) pour personnaliser les composants de la bibliothèque.
Points abordés
Vous découvrirez comment effectuer les actions suivantes :
- Incluez des composants
car-ui-lib
dans votre application Android. - Utilisez Gradle pour créer des applications Android et des RRO.
- Utilisez des RRO avec
car-ui-lib
.
Cet atelier de programmation n'explique pas en détail le fonctionnement des RRO. Pour en savoir plus, consultez les pages Modifier la valeur des ressources d'une application au moment de l'exécution et Résoudre les problèmes liés aux superpositions de ressources d'exécution.
Avant de commencer
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants:
Ordinateur avec ligne de commande (machine Linux, Mac ou Windows avec sous-système Windows pour Linux)
Appareil ou émulateur Android connecté à votre machine Consultez Télécharger le code source Android et Créer Android.
Connaissances de base sur les RRO
Créer une application Android
Durée:15 minutes
Dans cette section, vous allez créer un projet Android Studio.
Dans Android Studio, créez une application avec un
EmptyActivity
.Figure 1 : Créer une activité vide Nommez l'application
CarUiCodelab
, puis sélectionnez le langage Java. Vous pouvez également sélectionner un emplacement de fichier si vous le souhaitez. Acceptez les valeurs par défaut pour les autres paramètres.Figure 2. Nommer votre application Remplacez
activity_main.xml
par le bloc de code suivant:<?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>
Ce bloc de code affiche la chaîne
sample_text
, qui n'est pas définie.Ajoutez la chaîne de ressources
sample_text
et définissez-la sur "Hello World!" dans votre fichierstrings.xml
. Pour ouvrir ce fichier, sélectionnez app > src > main > res > values > strings.xml.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
Pour compiler votre application, cliquez sur le bouton vert Play (Lire) en haut à droite. L'APK est alors automatiquement installé sur votre émulateur ou votre appareil Android via Gradle.
La nouvelle application devrait s'ouvrir automatiquement sur votre émulateur ou votre appareil Android. Si ce n'est pas le cas, ouvrez l'application CarUiCodelab
depuis le lanceur d'applications, qui est maintenant installé.
Il se présente comme suit:

Ajouter car-ui-lib à votre application Android
Durée:15 minutes
Ajoutez car-ui-lib
à votre application:
Pour ajouter la dépendance
car-ui-lib
au fichierbuild.gradle
de votre projet, sélectionnez app > build.gradle. Vos dépendances doivent se présenter comme suit: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' }
Utiliser les composants de la bibliothèque car-ui-lib dans votre application Android
Maintenant que vous avez car-ui-lib
, ajoutez une barre d'outils à votre application.
Dans votre fichier
MainActivity.java
, remplacez la méthodeonCreate
:@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); }
Veillez à importer
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Pour utiliser le thème
Theme.CarUi.WithToolbar
, sélectionnez app > src > main > AndroidManifest.xml, puis mettez à jourAndroidManifest.xml
pour qu'il s'affiche comme suit:<?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>
Pour créer l'application, appuyez sur le bouton vert Play (Lire) comme précédemment.
Ajouter des RRO à votre application
Durée:30 minutes
Si vous connaissez les RRO, passez à la section suivante, Ajouter un contrôleur d'autorisation à votre application. Sinon, pour découvrir les principes de base des RRO, consultez Modifier la valeur des ressources d'une application au moment de l'exécution.
Ajouter un contrôleur d'autorisations à votre application
Pour contrôler les ressources qu'un package RRO superpose, ajoutez un fichier nommé overlayable.xml
au dossier /res
de votre application. Ce fichier sert de contrôleur d'autorisation entre votre application (la cible) et votre package RRO (la superposition).
Ajoutez
res/values/overlayable.xml
à votre application et copiez le contenu suivant dans votre fichier:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Étant donné que la chaîne
sample_text
doit pouvoir être superposée par un RRO, incluez le nom de la ressource dans le fichier overlayable.xml de l'application.Votre fichier
overlayable.xml
DOIT se trouver dansres/values/
. Sinon,OverlayManagerService
ne peut pas le localiser.Pour en savoir plus sur les ressources superposables et leur configuration, consultez la section Limiter les ressources superposables.
Créer un package RRO
Dans cette section, vous allez créer un package RRO pour remplacer la chaîne affichée ci-dessus de "Hello World!" par "Hello World RRO".
Pour créer un projet, sélectionnez File > New > New Project (Fichier > Nouveau > Nouveau projet). Veillez à sélectionner Aucune activité au lieu d'"Activité vide", car les packages RRO ne contiennent que des ressources.
Vos configurations ressemblent à celles illustrées ci-dessous. L'emplacement où elles sont enregistrées peut varier:
Après avoir créé le projet
CarUiRRO
, déclarez-le comme RRO en modifiantAndroidManifest.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>
Cette opération génère une erreur avec
@xml/sample_overlay
. Le fichierresourcesMap
mappe les noms de ressources du package cible au package RRO. Définir l'indicateurhasCode
surfalse
est obligatoire pour les packages RRO. De plus, les packages RRO ne sont pas autorisés à contenir des fichiers DEX.Copiez le bloc de code suivant dans
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Ajoutez
sample_text
à…/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>
Pour compiler votre cible RRO, appuyez sur le bouton vert Play (Lire) pour créer un build Gradle de votre RRO sur votre émulateur ou votre appareil Android.
Pour vérifier que votre RRO est correctement installé, exécutez la commande suivante:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Cette commande affiche des informations utiles sur l'état des packages RRO sur le système.
[ ]
indique que le RRO est installé et prêt à être activé.---
indique que le RRO est installé, mais contient des erreurs.[X]
signifie que le RRO est installé et activé.
Si votre superposition de ressources d'exécution contient des erreurs, consultez la section Résoudre les problèmes liés aux superpositions de ressources d'exécution avant de continuer.
Pour activer le RRO et vérifier qu'il est activé:
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
Votre application affiche la chaîne "Hello World RRO".

Félicitations ! Vous avez créé votre premier RRO.
Lorsque vous utilisez des RRO, vous pouvez utiliser les indicateurs --no-resource-deduping
et --no-resource-removal
d'Android Asset Packaging Tool (AAPT2) décrits dans la section Options de lien.
Il n'est pas nécessaire d'ajouter les indicateurs dans cet atelier de programmation, mais nous vous suggérons de les utiliser dans vos RRO pour éviter la suppression de ressources (et les problèmes de débogage). Vous pouvez les ajouter au fichier build.gradle
de votre RRO comme suit:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Pour en savoir plus sur ces options, consultez les sections Créer le package et AAPT2.
Modifier les composants car-ui-lib
à l'aide de RRO dans votre application Android
Cette page explique comment utiliser une superposition de ressources d'exécution (RRO) pour modifier les composants de la bibliothèque car-ui-lib
dans votre application Android.
Définir la couleur d'arrière-plan de la barre d'outils
Durée:15 minutes
Pour modifier la couleur d'arrière-plan de la barre d'outils:
Ajoutez la valeur suivante à votre application RRO et définissez la ressource sur vert clair (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
La bibliothèque
car-ui-lib
contient une ressource nomméecar_ui_toolbar_background
. Lorsque cette ressource est contenue dans la configuration d'un RRO, la barre d'outils ne change pas, car la mauvaise valeur est ciblée.Dans le fichier
AndroidManifest.xml
de votre RRO, mettez à jourtargetName
pour qu'il pointe verscar-ui-lib
:… android:targetName="car-ui-lib" …
Vous devez créer un package de RRO pour chaque package cible que vous souhaitez utiliser. Par exemple, lorsque vous créez des superpositions pour deux cibles différentes, vous devez créer deux APK de superposition.
Créez, vérifiez, installez et activez le RRO de la même manière que précédemment.
Votre application se présente comme suit:

Mises en page et styles des ROP
Durée:15 minutes
Dans cet exercice, vous allez créer une application semblable à celle que vous avez créée précédemment. Cette application permet de superposer la mise en page. Suivez la même procédure que précédemment ou modifiez votre application existante.
Veillez à ajouter les lignes suivantes à
overlayable.xml
:<?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>
Assurez-vous que
activity_main.xml
s'affiche comme suit:<?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>
Dans votre application RRO, créez un
res/layout/activity_main.xml
et ajoutez les éléments suivants:<?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>
Mettez à jour
res/values/styles.xml
pour ajouter notre style à la 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>
Modifiez le
targetName
dansAndroidManifest.xml
pour qu'il pointe vers le nom de votre nouvelle application:… android:targetName="CarUiCodelab" …
Ajoutez les ressources au fichier
sample_overlay.xml
de votre 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>
Créez et installez l'application et le RRO de la même manière qu'auparavant (bouton Play vert). Veillez à activer votre RRO.
L'application et le RRO s'affichent comme suit. Le texte Hello World de la disposition RRO est vert et centré, comme indiqué dans la disposition RRO.

Ajouter CarUiRecyclerView à votre application
Durée:15 minutes
L'interface CarUiRecyclerView
fournit des API pour accéder à un RecyclerView
personnalisé via des ressources car-ui-lib
. Par exemple, CarUiRecyclerView
vérifie un indicateur au moment de l'exécution pour déterminer si la barre de défilement doit être activée ou non, puis sélectionne la mise en page correspondante.

Pour ajouter un
CarUiRecyclerView
, ajoutez-le à vos fichiersactivity_main.xml
etMainActivity.java
. Vous pouvez créer une application à partir de zéro ou modifier l'application existante. Si vous modifiez l'application existante, veillez à supprimer les ressources non déclarées deoverlayable.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"/>
L'erreur suivante peut s'afficher, mais vous pouvez l'ignorer:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Tant que votre classe est correctement orthographiée et que vous avez ajouté
car-ui-lib
comme dépendance, vous pouvez compiler et compiler votre APK. Pour supprimer l'erreur, sélectionnez File > Invalidate Caches (Fichier > Invalider les caches), puis cliquez sur Invalidate and Restart (Invalider et redémarrer).Ajoutez le code suivant à
MainActivity.java
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; }
Compilez et installez votre application comme d'habitude.
Un CarUiRecyclerView
s'affiche alors:

Utiliser une RRO pour supprimer la barre de défilement
Durée:10 minutes
Cet exercice vous explique comment utiliser un RRO pour supprimer la barre de défilement de CarUiRecyclerView
.
Dans votre RRO, ajoutez et modifiez les fichiers suivants:
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>
La ressource
car_ui_scrollbar_enable
est une ressource booléennecar-ui-lib
, qui contrôle si la barre de défilement optimisée pour les voitures avec les boutons "Haut" et "Bas" dansCarUiRecyclerView
est présente ou non. LorsqueCarUiRecyclerView
est défini surfalse
, il se comporte comme unRecyclerView
AndroidX.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>
Compilez et installez votre application comme d'habitude. La barre de défilement est désormais supprimée de CarUiRecyclerView
:

Utiliser une mise en page pour superposer la barre de défilement de CarUiRecyclerView
Durée:15 minutes
Dans cet exercice, vous allez modifier la mise en page de la barre de défilement CarUiRecyclerView
.
Ajoutez et modifiez les fichiers suivants dans votre application 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>
Pour superposer un fichier de mise en page, vous devez ajouter tous les ID et les attributs d'espace de noms à l'
overlay.xml
de votre RRO. Consultez les fichiers ci-dessous.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>
Nous vous recommandons d'examiner la façon dont ces fichiers interagissent.
Pour plus de simplicité, les dimensions et les couleurs sont codées en dur. Toutefois, il est recommandé de déclarer ces valeurs dans
dimens.xml
etcolors.xml
, ou même de les désigner comme fichiers de couleurs dans le dossierres/color/
. Pour en savoir plus, consultez le style de code Java AOSP pour les contributeurs.Compilez et installez votre application comme d'habitude. Vous avez créé
CarUiRecyclerView
avec une barre de défilement bleue et des rails gris.
Félicitations ! Les deux flèches apparaissent en bas de la barre de défilement. Vous avez appliqué avec succès une RRO à un fichier de ressources de mise en page car-ui-lib
à l'aide du système de compilation Gradle via Android Studio.

Éléments de liste RRO
Durée:15 minutes
À ce stade, vous avez appliqué un RRO aux composants car-ui-lib
à l'aide de composants de framework (et non d'AndroidX). Pour utiliser des composants AndroidX dans une RRO, vous devez ajouter les dépendances de ce composant à la fois à l'application et à la build.gradle.
de la RRO. Vous devez également ajouter le attrs
de ce composant à overlayable.xml
dans votre application, ainsi que le sample_overlay.xml
dans votre RRO.
Notre bibliothèque (car-ui-lib
) utilise ConstraintLayout
ainsi que d'autres composants AndroidX. Son overlayable.xml
peut donc se présenter comme suit:
<?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>
Modifiez la mise en page des éléments de la liste dans
CarUiRecyclerView
à l'aide deConstraintLayout
. Ajoutez ou modifiez les fichiers suivants dans votre 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
fait référence à plusieurs composants/ressources qui ne sont pas inclus en tant que dépendances de l'application. Il s'agit de ressourcescar-ui-lib
. Pour résoudre ce problème, ajoutezcar-ui-lib
en tant que dépendance à votre application RRO dansapp/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' }
Le titre et le corps du texte sont désormais alignés à droite au lieu de l'être à gauche.

Nous n'avons appliqué une RRO à car-ui-lib
qu'à l'aide de composants AndroidX (ConstraintLayout
) lorsque ses attributs étaient présents dans le fichier car-ui-lib
nommé overlayable.xml
ainsi que dans la RRO sample_overlay.xml
. Vous pouvez faire quelque chose de similaire dans votre propre application. Il vous suffit d'ajouter tous les attrs
correspondants au overlayable.xml
de votre application, comme pour car-ui-lib
.
Toutefois, il n'est pas possible de RRO une application utilisant des composants AndroidX lorsque l'application a car-ui-lib
comme dépendance dans son build.gradle
(lorsque l'application utilise des composants car-ui-lib
). Étant donné que les mappages d'attributs étaient déjà définis dans le fichier overlayable.xml
de la bibliothèque car-ui-lib
, les ajouter au fichier overlayable.xml
de votre application avec car-ui-lib
en tant que dépendance entraînerait une erreur mergeDebugResources
comme celle ci-dessous. En effet, ces attributs sont présents dans plusieurs fichiers overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'