Utilisez la bibliothèque car-ui-lib
pour lancer des systèmes d'infodivertissement (IVI) auto-cohérents embarqués dans le véhicule. Cet atelier de programmation vous présente car-ui-lib
et vous explique comment utiliser les superpositions de ressources d'exécution (RRO) pour personnaliser les composants de la bibliothèque.
Ce que vous apprendrez
Comment:
- Incluez les composants
car-ui-lib
dans votre application Android. - Utilisez Gradle pour créer des applications Android et des RRO.
- Utilisez les RRO avec
car-ui-lib
.
Cet atelier de programmation ne détaille pas le fonctionnement des RRO. Consultez Modifier la valeur des ressources d’une application au moment de l’exécution et Dépanner les superpositions de ressources d’exécution pour en savoir plus.
Avant de commencer
Conditions préalables
Avant de commencer, assurez-vous d'avoir :
Ordinateur avec ligne de commande (machine Linux, Mac ou machine Windows avec sous-système Windows pour Linux).
Appareil ou émulateur Android connecté à votre machine. Voir Télécharger la source Android et Créer Android .
Connaissance de base des RRO.
Créer une nouvelle application Android
Durée : 15 minutes
Dans cette section, vous créez un nouveau projet Android Studio.
Dans Android Studio, créez une application avec un
EmptyActivity
.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 paramètres restants.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 ressource
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 créer votre application, cliquez sur le bouton vert Play en haut à droite. Cela installe automatiquement l'apk sur votre émulateur ou votre appareil Android via Gradle.
La nouvelle application devrait s'ouvrir automatiquement sur votre émulateur ou votre appareil Android. Sinon, ouvrez l'application CarUiCodelab
à partir du lanceur d'applications, qui est maintenant installé. Cela ressemble à ceci :
Ajoutez 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 devraient apparaître comme ceci :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' }
Utilisez les composants car-ui-lib dans votre application Android
Maintenant que vous disposez 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); }
Assurez-vous d'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 apparaisse 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 comme avant.
Ajoutez des RRO à votre application
Durée : 30 minutes
Si vous êtes familier avec les RRO, passez à la section suivante, Ajouter un contrôleur d'autorisation à votre application . Sinon, pour découvrir les bases des RRO, consultez Modifier la valeur des ressources d'une application au moment de l'exécution .
Ajoutez un contrôleur d'autorisation à 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 résider dansres/values/
. Sinon,OverlayManagerService
ne peut pas le localiser.Pour en savoir plus sur les ressources superposables et sur la façon dont elles peuvent être configurées, consultez Restreindre les ressources superposables .
Créer un package RRO
Dans cette section, vous créez un package RRO pour modifier la chaîne affichée ci-dessus de « Hello World ! » à "Bonjour le monde RRO".
Pour créer un nouveau projet, sélectionnez Fichier > Nouveau > Nouveau projet . Assurez-vous de sélectionner Aucune activité au lieu d'Activité vide, car les packages RRO ne contiennent que des ressources.
Vos configurations apparaissent de manière similaire à celles illustrées ci-dessous. L'emplacement où ils sont enregistrés peut différer :
Après avoir créé le nouveau projet
CarUiRRO
, déclarez le projet 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>
Cela crée une erreur avec
@xml/sample_overlay
. Le fichierresourcesMap
mappe les noms de ressources du package cible au package RRO.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 créer votre cible RRO, appuyez sur le bouton vert Lecture pour créer une version Gradle de votre RRO sur votre émulateur ou votre appareil Android.
Pour vérifier que votre RRO est correctement installé, exécutez :
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 RRO contient des erreurs, consultez Résoudre les 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 ».
Toutes nos félicitations! Vous avez créé votre premier RRO.
Lorsque vous utilisez des RRO, vous souhaiterez peut-être utiliser les indicateurs --no-resource-deduping
et --no-resource-removal
d'Android Asset Packaging Tool (AAPT2) décrits dans 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 ceci :
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Pour en savoir plus sur ces indicateurs, consultez Créer le package et AAPT2 .
Modifier les composants car-ui-lib
à l'aide des RRO dans votre application Android
Cette page décrit 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 changer 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 vif (
#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
AndroidManifest.xml
de votre RRO, mettez à jourtargetName
pour qu'il pointe verscar-ui-lib
:… android:targetName="car-ui-lib" …
Vous DEVEZ créer un nouveau package RRO pour chaque package cible que vous souhaitez RRO. Par exemple, lors de la création de superpositions pour deux cibles différentes, vous devez créer deux apks de superposition.
Créez, vérifiez, installez et activez le RRO de la même manière qu'auparavant.
Votre application apparaît comme ceci :
Dispositions et styles RRO
Durée : 15 minutes
Dans cet exercice, vous allez créer une nouvelle application similaire à celle que vous avez créée précédemment. Cette application permet de superposer la mise en page. Suivez les mêmes étapes que précédemment ou modifiez votre application existante.
Assurez-vous d'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
apparaît 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 ce qui suit :<?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 au 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
dans 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'avant (bouton vert Play ). Assurez-vous d'activer votre RRO.
L'application et le RRO s'affichent comme suit. Le texte Hello World RRO est vert et centré comme spécifié dans la mise en page RRO.
Ajoutez CarUiRecyclerView à votre application
Durée : 15 minutes
L'interface CarUiRecyclerView
fournit des API pour accéder à un RecyclerView
personnalisé via les 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 et sélectionne la disposition correspondante.
Pour ajouter un
CarUiRecyclerView
, ajoutez-le à vos fichiersactivity_main.xml
etMainActivity.java
. Vous pouvez soit créer une nouvelle application à partir de zéro, soit 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 apparaître, que vous pouvez 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
en tant que dépendance, vous pouvez créer et compiler votre apk. Pour supprimer l'erreur, sélectionnez Fichier > Invalider les caches, puis cliquez sur Invalider et redémarrer.Ajoutez ce qui suit à
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; }
Créez et installez votre application comme avant.
Vous voyez maintenant un CarUiRecyclerView
:
Utilisez un RRO pour supprimer la barre de défilement
Durée : 10 minutes
Cet exercice vous montre 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 la voiture avec les boutons Haut et Bas dansCarUiRecyclerView
est présente ou non. Lorsqu'il est défini surfalse
,CarUiRecyclerView
agit comme un 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>
Créez et installez votre application comme avant. La barre de défilement est désormais supprimée de CarUiRecyclerView
:
Utiliser une mise en page pour superposer la barre de défilement CarUiRecyclerView
Durée : 15 minutes
Dans cet exercice, vous allez modifier la disposition 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 attributs d'espace de noms au
overlay.xml
de votre RRO. Voir 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>
Il est suggéré d'examiner comment ces fichiers interagissent.
Pour plus de simplicité, les dimensions et les couleurs sont codées en dur. Cependant, une bonne pratique consiste à déclarer ces valeurs dans
dimens.xml
etcolors.xml
ou même à les désigner comme fichiers de couleur dans le dossierres/color/
. Pour en savoir plus, consultez Style de code Java AOSP pour les contributeurs .Créez et installez votre application comme avant. Vous avez construit
CarUiRecyclerView
avec une barre de défilement bleue et des rails gris.
Toutes nos félicitations! Les deux flèches apparaissent en bas de la barre de défilement. Vous avez appliqué avec succès un RRO à un fichier de ressources de mise en page car-ui-lib
à l'aide du système de construction Gradle via Android Studio.
Éléments de la liste RRO
Durée : 15 minutes
Jusqu'à présent, 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 un RRO, vous devez ajouter les dépendances de ce composant à la fois à l'application et au build.gradle.
Vous devez également ajouter attrs
de ce composant à overlayable.xml
dans votre application, ainsi qu'à sample_overlay.xml
dans votre RRO.
Notre bibliothèque ( car-ui-lib
) utilise ConstraintLayout
ainsi que d'autres composants AndroidX, donc son overlayable.xml
pourrait ressembler à ceci :
<?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 disposition des éléments de liste dans
CarUiRecyclerView
à l’aideConstraintLayout
. 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 références à plusieurs composants/ressources qui ne sont pas inclus en tant que dépendances de l'application. Ce sont des ressourcescar-ui-lib
. Vous pouvez résoudre ce problème en ajoutantcar-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 sont désormais alignés à droite au lieu d'être alignés à gauche.
Nous n'avons appliqué un RRO à car-ui-lib
à l'aide de composants AndroidX ( ConstraintLayout
) que lorsque ses attributs étaient présents dans le fichier car-ui-lib
nommé overlayable.xml
ainsi que dans le RRO sample_overlay.xml
. Il est possible de faire quelque chose de similaire dans votre propre application. Ajoutez simplement toutes les attrs
correspondantes au overlayable.xml
de votre application, similaire à car-ui-lib
.
Cependant, 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 overlayable.xml
de la bibliothèque car-ui-lib
, les ajouter au overlayable.xml
de votre application avec car-ui-lib
comme dépendance provoquerait 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'