Utilizza la libreria car-ui-lib
per avviare sistemi di infotainment (IVI) in auto coerenti. Questo codelab introduce car-ui-lib
e spiega come utilizzare gli overlay delle risorse di runtime (RRO) per personalizzare i componenti della libreria.
Cosa imparerai
Procedura:
- Includi componenti
car-ui-lib
nella tua app per Android. - Utilizza Gradle per creare app e RRO per Android.
- Utilizza RRO con
car-ui-lib
.
Questo codelab non descrive nel dettaglio il funzionamento dei report RRO. Per saperne di più, consulta Modificare il valore delle risorse di un'app in fase di runtime e Risolvere i problemi relativi agli overlay delle risorse di runtime.
Prima di iniziare
Prerequisiti
Prima di iniziare, assicurati di avere:
Computer con riga di comando (macchina Linux, Mac o Windows con Subsistema Windows per Linux).
Dispositivo Android o emulatore connesso alla tua macchina. Consulta Scarica il codice sorgente di Android e Compila Android.
Conoscenza di base delle RRO.
Creare una nuova app per Android
Durata: 15 minuti
In questa sezione viene creato un nuovo progetto Android Studio.
In Android Studio, crea un'app con un
EmptyActivity
.Figura 1.Crea un'attività vuota Assegna un nome all'app
CarUiCodelab
, quindi seleziona il linguaggio Java. Se vuoi, puoi anche selezionare una posizione del file. Accetta i valori predefiniti per le impostazioni rimanenti.Figura 2. Assegna un nome all'app Sostituisci
activity_main.xml
con il seguente blocco di codice:<?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>
Questo blocco di codice mostra la stringa
sample_text
, che non è definita.Aggiungi la stringa della risorsa
sample_text
e impostala su "Hello World!" nelstrings.xml
file. Per aprire questo file, seleziona 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>
Per creare l'app, fai clic sul pulsante verde Riproduci in alto a destra. In questo modo, l'APK viene installato automaticamente sull'emulatore o sul dispositivo Android tramite Gradle.
La nuova app dovrebbe aprirsi automaticamente sull'emulatore o sul dispositivo Android. In caso contrario, apri l'app CarUiCodelab
dall'Avvio app, che ora è installata.
Viene visualizzato come segue:

Aggiungere car-ui-lib all'app per Android
Durata: 15 minuti
Aggiungi car-ui-lib
alla tua app:
Per aggiungere la dipendenza
car-ui-lib
al filebuild.gradle
del progetto, seleziona app > build.gradle. Le dipendenze dovrebbero essere visualizzate come segue: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' }
Utilizzare i componenti della libreria car-ui-lib nell'app per Android
Ora che hai car-ui-lib
, aggiungi una barra degli strumenti alla tua app.
Nel file
MainActivity.java
, sovrascrivi il metodoonCreate
:@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); }
Assicurati di importare
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Per utilizzare il tema
Theme.CarUi.WithToolbar
, seleziona app > src > main > AndroidManifest.xml e poi aggiornaAndroidManifest.xml
in modo che venga visualizzato come segue:<?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>
Per compilare l'app, premi il pulsante verde Riproduci come prima.
Aggiungere RRO all'app
Durata: 30 minuti
Se hai dimestichezza con le RRO, vai alla sezione successiva, Aggiungere un controller delle autorizzazioni all'app. In caso contrario, per conoscere le nozioni di base sulle RRO, consulta Modificare il valore delle risorse di un'app in fase di esecuzione.
Aggiungere un controllore delle autorizzazioni all'app
Per controllare le risorse sovrapposte da un pacchetto RRO, aggiungi un file denominato
overlayable.xml
alla cartella /res
dell'app. Questo file funge da controllore delle autorizzazioni tra la tua app (il target) e il pacchetto RRO (l'overlay).
Aggiungi
res/values/overlayable.xml
alla tua app e copia i seguenti contenuti nel file:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Poiché la stringa
sample_text
deve essere sovrapponibile da un RRO, includi il nome della risorsa in overlayable.xml dell'app.Il file
overlayable.xml
DEVE trovarsi inres/values/
. In caso contrario,OverlayManagerService
non può trovarlo.Per scoprire di più sulle risorse sovrapponibili e su come possono essere configurate, consulta l'articolo Limitare le risorse sovrapponibili.
Creare un pacchetto RRO
In questa sezione, crei un pacchetto RRO per modificare la stringa visualizzata sopra da "Hello World!" a "Hello World RRO".
Per creare un nuovo progetto, seleziona File > Nuovo > Nuovo progetto. Assicurati di selezionare Nessuna attività anziché Attività vuota, poiché i pacchetti RRO contengono solo risorse.
Le configurazioni vengono visualizzate in modo simile a quelle illustrate di seguito. La posizione in cui vengono salvati può variare:
Dopo aver creato il nuovo progetto
CarUiRRO
, dichiaralo come RRO modificandoAndroidManifest.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>
In questo modo viene creato un errore con
@xml/sample_overlay
. Il fileresourcesMap
mappa i nomi delle risorse dal pacchetto di destinazione al pacchetto RRO. L'impostazione del flaghasCode
sufalse
è obbligatoria per i pacchetti RRO. Inoltre, i pacchetti RRO non possono contenere file DEX.Copia il seguente blocco di codice in
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Aggiungi
sample_text
a…/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>
Per compilare il target RRO, premi il pulsante verde Riproduci per creare una compilazione Gradle della tua RRO sull'emulatore o sul dispositivo Android.
Per verificare che l'RRO sia installato correttamente, esegui:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Questo comando mostra informazioni utili sullo stato dei pacchetti RRO sul sistema.
[ ]
indica che l'RRO è installato e pronto per essere attivato.---
indica che il blocco RRO è installato, ma contiene errori.[X]
indica che l'RRO è installato e attivato.
Se il file RRO contiene errori, consulta la sezione Risolvere i problemi relativi agli overlay delle risorse di runtime prima di continuare.
Per attivare l'RRO e verificare che sia attivo:
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
L'app mostra la stringa "Hello World RRO".

Complimenti! Hai creato il tuo primo RRO.
Quando utilizzi i file RRO, ti consigliamo di utilizzare i flag --no-resource-deduping
e --no-resource-removal
di Android Asset Packaging Tool (AAPT2) descritti in Opzioni di collegamento.
Non è necessario aggiungere i flag in questo codelab, ma ti consigliamo di utilizzarli
nei tuoi RRO per evitare la rimozione delle risorse (e i problemi di debug). Puoi aggiungerli al file build.gradle
del tuo RRO nel seguente modo:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Per scoprire di più su questi flag, consulta Compilare il pacchetto e AAPT2.
Modificare i componenti car-ui-lib
utilizzando gli RRO nell'app per Android
Questa pagina descrive come utilizzare un overlay delle risorse di runtime (RRO) per modificare i componenti della libreria car-ui-lib
nella tua app per Android.
Impostare il colore di sfondo della barra degli strumenti
Durata: 15 minuti
Per modificare il colore di sfondo della barra degli strumenti:
Aggiungi il seguente valore all'app RRO e imposta la risorsa su verde brillante (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
La libreria
car-ui-lib
contiene una risorsa denominatacar_ui_toolbar_background
. Quando questa risorsa è contenuta nella configurazione di un RRO, la barra degli strumenti non cambia perché è scelto come target il valore sbagliato.Nel file
AndroidManifest.xml
per il tuo RRO, aggiornatargetName
in modo che rimandi acar-ui-lib
:… android:targetName="car-ui-lib" …
DEVI creare un nuovo pacchetto RRO per ogni pacchetto target che vuoi eseguire RRO. Ad esempio, quando crei overlay per due target diversi, devi creare due apk overlay.
Crea, verifica, installa e attiva l'RRO come prima.
L'app viene visualizzata come segue:

Layout e stili RRO
Durata: 15 minuti
In questo esercizio, crei una nuova app simile a quella creata in precedenza. Questa app consente di sovrapporre il layout. Segui la stessa procedura di prima o modifica la tua app esistente.
Assicurati di aggiungere le seguenti righe a
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>
Assicurati che
activity_main.xml
venga visualizzato come segue:<?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>
Nell'app RRO, crea un
res/layout/activity_main.xml
e aggiungi quanto segue:<?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>
Aggiorna
res/values/styles.xml
per aggiungere il nostro stile al 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>
Modifica
targetName
inAndroidManifest.xml
in modo che rimandi al nome della nuova app:… android:targetName="CarUiCodelab" …
Aggiungi le risorse al file
sample_overlay.xml
nel tuo 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>
Crea e installa l'app e l'RRO come prima (pulsante verde Riproduci). Assicurati di attivare l'RRO.
L'app e l'RRO vengono visualizzati come segue. Il testo RRO di Hello World è verde e centrato come specificato nel layout RRO.

Aggiungi CarUiRecyclerView alla tua app
Durata: 15 minuti
L'interfaccia CarUiRecyclerView
fornisce API per accedere a un RecyclerView
personalizzato tramite le risorse car-ui-lib
. Ad esempio, CarUiRecyclerView
controlla un flag in fase di runtime per determinare se la barra di scorrimento deve essere attivata o meno
e seleziona il layout corrispondente.

Per aggiungere un
CarUiRecyclerView
, aggiungilo ai fileactivity_main.xml
eMainActivity.java
. Puoi creare una nuova app da zero o modificare quella esistente. Se modifichi l'app esistente, assicurati di rimuovere le risorse non dichiarate daoverlayable.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"/>
Potrebbe essere visualizzato il seguente errore, che puoi ignorare:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Se la classe è scritta correttamente e hai aggiunto
car-ui-lib
come dipendenza, puoi compilare e compilare l'APK. Per rimuovere l'errore, seleziona File > Invalida cache e poi fai clic su Invalida e riavvia.Aggiungi quanto segue a
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; }
Crea e installa l'app come prima.
Ora viene visualizzato un CarUiRecyclerView
:

Utilizzare un RRO per rimuovere la barra di scorrimento
Durata: 10 minuti
Questo esercizio mostra come utilizzare un RRO per rimuovere la barra di scorrimento da
CarUiRecyclerView
.
Nell'RRO, aggiungi e modifica i seguenti file:
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 risorsa
car_ui_scrollbar_enable
è una risorsa booleanacar-ui-lib
, che controlla se la barra di scorrimento ottimizzata per le auto con i pulsanti Su e Giù inCarUiRecyclerView
è presente o meno. Se impostato sufalse
,CarUiRecyclerView
si comporta come unRecyclerView
di 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>
Crea e installa l'app come prima. La barra di scorrimento è stata rimossa da
CarUiRecyclerView
:

Utilizza un layout per sovrapporre la barra di scorrimento di CarUiRecyclerView
Durata: 15 minuti
In questo esercizio modifichi il layout della barra di scorrimento di CarUiRecyclerView
.
Aggiungi e modifica i seguenti file nell'app 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>
Per sovrapporre un file di layout, devi aggiungere tutti gli attributi ID e del namespace al
overlay.xml
del tuo RRO. Consulta i file riportati di seguito.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>
Ti consigliamo di esaminare il modo in cui questi file interagiscono.
Per semplicità, le dimensioni e i colori sono hardcoded. Tuttavia, una buona prassi è dichiarare questi valori in
dimens.xml
ecolors.xml
o anche designarli come file di colore nella cartellares/color/
. Per saperne di più, consulta la sezione Stile di codice Java AOSP per i collaboratori.Crea e installa l'app come prima. Hai creato
CarUiRecyclerView
con una barra di scorrimento blu e riquadri grigi.
Complimenti! Entrambe le frecce vengono visualizzate nella parte inferiore della barra di scorrimento. Hai applicato correttamente un RRO a un file di risorse di layout car-ui-lib
utilizzando il sistema di compilazione Gradle tramite Android Studio.

Voci elenco RRO
Durata: 15 minuti
A questo punto, hai applicato un RRO ai componenti car-ui-lib
utilizzando i componenti del framework (non AndroidX). Per utilizzare i componenti AndroidX in un RRO, devi aggiungere le dipendenze del componente sia all'app sia all'RRO build.gradle.
. Devi anche aggiungere il attrs
del componente a overlayable.xml
nell'app, nonché il sample_overlay.xml
nell'RRO.
La nostra libreria (car-ui-lib
) utilizza ConstraintLayout
e altri componenti AndroidX, pertanto il suo overlayable.xml
potrebbe avere il seguente aspetto:
<?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>
Modifica il layout degli elementi dell'elenco in
CarUiRecyclerView
utilizzandoConstraintLayout
. Aggiungi o modifica i seguenti file nell'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
fa riferimento a diversi componenti/risorse che non sono inclusi come dipendenze dell'app. Si tratta di risorsecar-ui-lib
. Puoi risolvere il problema aggiungendocar-ui-lib
come dipendenza all'app RRO inapp/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' }
Il titolo e il corpo sono ora allineati a destra anziché a sinistra.

Abbiamo applicato un RRO a car-ui-lib
utilizzando i componenti AndroidX
(ConstraintLayout
) solo quando i relativi attributi erano presenti nel file car-ui-lib
denominato overlayable.xml
, nonché nell'RRO sample_overlay.xml
. È possibile fare qualcosa di simile nella tua app. Basta aggiungere tutti i attrs
corrispondenti al overlayable.xml
dell'app, in modo simile a car-ui-lib
.
Tuttavia, non è possibile eseguire il RRO di un'app che utilizza componenti AndroidX quando
l'app ha car-ui-lib
come dipendenza nel suo build.gradle
(quando l'app utilizza
componenti car-ui-lib
). Poiché le mappature degli attributi erano già definite nel overlayable.xml
della raccolta car-ui-lib
, aggiungerle al overlayable.xml
dell'app con car-ui-lib
come dipendenza causerebbe un errore mergeDebugResources
come quello riportato di seguito. Questo perché questi attributi
sono presenti in più file overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'