Utilice la biblioteca car-ui-lib
para iniciar sistemas de información y entretenimiento (IVI) autoconsistentes en el vehículo. Este codelab le presenta car-ui-lib
y cómo puede utilizar superposiciones de recursos en tiempo de ejecución (RRO) para personalizar los componentes de la biblioteca.
lo que aprenderás
Cómo:
- Incluya componentes
car-ui-lib
en su aplicación de Android. - Utilice Gradle para crear aplicaciones y RRO de Android.
- Utilice RRO con
car-ui-lib
.
Este codelab no detalla cómo funcionan los RRO. Consulte Cambiar el valor de los recursos de una aplicación en tiempo de ejecución y Solucionar problemas de superposiciones de recursos en tiempo de ejecución para obtener más información.
Antes de que empieces
Requisitos previos
Antes de comenzar, asegúrese de tener:
Computadora con línea de comando (máquina Linux, Mac o máquina Windows con Subsistema Windows para Linux).
Dispositivo Android o emulador conectado a su máquina. Consulte Descargar la fuente de Android y Compilación de Android .
Conocimientos básicos de RRO.
Crear una nueva aplicación de Android
Duración: 15 minutos
En esta sección, crea un nuevo proyecto de Android Studio.
En Android Studio, cree una aplicación con una
EmptyActivity
.Figura 1. Crear una actividad vacía Nombra la aplicación
CarUiCodelab
y luego selecciona el lenguaje Java. También puede seleccionar una ubicación de archivo si lo desea. Acepte los valores predeterminados para las configuraciones restantes.Figura 2. Asigne un nombre a su aplicación Reemplace
activity_main.xml
con el siguiente bloque de código:<?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>
Este bloque de código muestra la cadena
sample_text
, que no está definida.Agregue la cadena de recurso
sample_text
y configúrela en "¡Hola mundo!" en su archivostrings.xml
. Para abrir este archivo, seleccione aplicación > src > principal > res > valores > strings.xml .<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
Para crear su aplicación, haga clic en el botón verde Reproducir en la parte superior derecha. Al hacerlo, se instala automáticamente el apk en su emulador o dispositivo Android a través de Gradle.
La nueva aplicación debería abrirse automáticamente en su emulador o dispositivo Android. De lo contrario, abra la aplicación CarUiCodelab
desde el iniciador de aplicaciones, que ahora está instalado. Aparece así:
![Abra la nueva aplicación CarUiCodelab](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=es)
Añade car-ui-lib a tu aplicación de Android
Duración: 15 minutos
Agregue car-ui-lib
a su aplicación:
Para agregar la dependencia
car-ui-lib
al archivobuild.gradle
de su proyecto, seleccione aplicación > build.gradle . Tus dependencias deberían aparecer así: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' }
Utilice componentes car-ui-lib en su aplicación de Android
Ahora que tienes car-ui-lib
, agrega una barra de herramientas a tu aplicación.
En su archivo
MainActivity.java
, sobrescriba el métodoonCreate
:@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); }
Asegúrese de importar
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Para usar el tema
Theme.CarUi.WithToolbar
, seleccione aplicación > src > principal > AndroidManifest.xml y luego actualiceAndroidManifest.xml
para que aparezca de la siguiente manera:<?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>
Para crear la aplicación, presione el botón verde Reproducir como antes.
Agregue RRO a su aplicación
Duración: 30 minutos
Si está familiarizado con los RRO, vaya a la siguiente sección, Agregar un controlador de permisos a su aplicación . De lo contrario, para conocer los conceptos básicos de las RRO, consulte Cambiar el valor de los recursos de una aplicación en tiempo de ejecución .
Agregue un controlador de permisos a su aplicación
Para controlar qué recursos superpone un paquete RRO, agregue un archivo llamado overlayable.xml
a la carpeta /res
de su aplicación. Este archivo sirve como controlador de permisos entre su aplicación (el destino ) y su paquete RRO (la superposición ).
Agregue
res/values/overlayable.xml
a su aplicación y copie el siguiente contenido en su archivo:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Dado que un RRO debe poder superponer la cadena
sample_text
, incluya el nombre del recurso en el archivo overlayable.xml de la aplicación.Su archivo
overlayable.xml
DEBE residir enres/values/
. De lo contrario,OverlayManagerService
no puede localizarlo.Para obtener más información sobre los recursos superpuestos y cómo se pueden configurar, consulte Restringir recursos superpuestos .
Crear un paquete RRO
En esta sección, creará un paquete RRO para cambiar la cadena que se muestra arriba de "¡Hola mundo!" a "Hola mundo RRO".
Para crear un nuevo proyecto, seleccione Archivo > Nuevo > Nuevo proyecto . Asegúrese de seleccionar Sin actividad en lugar de Actividad vacía, ya que los paquetes RRO solo contienen recursos.
Sus configuraciones son similares a las que se ilustran a continuación. La ubicación en la que se guardan puede diferir:
Después de crear el nuevo proyecto
CarUiRRO
, declara el proyecto como 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>
Hacer esto crea un error con
@xml/sample_overlay
. El archivoresourcesMap
asigna nombres de recursos del paquete de destino al paquete RRO.Copie el siguiente bloque de código en
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Agregue
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>
Para crear su objetivo RRO, presione el botón verde Reproducir para crear una compilación Gradle de su RRO en su emulador o dispositivo Android.
Para verificar que su RRO esté instalado correctamente, ejecute:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Este comando muestra información útil sobre el estado de los paquetes RRO en el sistema.
-
[ ]
indica que el RRO está instalado y listo para ser activado. -
---
indica que el RRO está instalado pero contiene errores. -
[X]
significa que el RRO está instalado y activado.
Si su RRO contiene errores, consulte Solucionar problemas de superposiciones de recursos de tiempo de ejecución antes de continuar.
-
Para habilitar el RRO y verificar que esté habilitado:
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
Su aplicación muestra la cadena "Hello World RRO".
![¡Hola Mundo RRO!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=es)
¡Felicidades! Ha creado su primer RRO.
Cuando utilice RRO, es posible que desee utilizar los indicadores de la herramienta de empaquetado de activos de Android (AAPT2) --no-resource-deduping
y --no-resource-removal
que se describen en Opciones de enlace . No es necesario agregar las banderas en este codelab, pero le sugerimos que las use en sus RRO para evitar la eliminación de recursos (y dolores de cabeza de depuración). Puedes agregarlos al archivo build.gradle
de tu RRO de esta manera:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Para obtener más información sobre estas marcas, consulte Compilación del paquete y AAPT2 .
Modifique los componentes car-ui-lib
usando RRO en su aplicación de Android
Esta página describe cómo puede utilizar una superposición de recursos de tiempo de ejecución (RRO) para modificar componentes de la biblioteca car-ui-lib
en su aplicación de Android.
Establecer el color de fondo de la barra de herramientas
Duración: 15 minutos
Para cambiar el color de fondo de la barra de herramientas:
Agregue el siguiente valor a su aplicación RRO y configure el recurso en verde brillante (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
La biblioteca
car-ui-lib
contiene un recurso llamadocar_ui_toolbar_background
. Cuando este recurso está contenido en la configuración de un RRO, la barra de herramientas no cambia porque se apunta al valor incorrecto.En
AndroidManifest.xml
de su RRO, actualicetargetName
para que apunte acar-ui-lib
:… android:targetName="car-ui-lib" …
DEBE crear un nuevo paquete RRO para cada paquete de destino que desee RRO. Por ejemplo, al crear superposiciones para dos objetivos diferentes, debes crear dos aplicaciones de superposición.
Cree, verifique, instale y habilite el RRO de la misma manera que antes.
Su aplicación se ve así:
![Nuevo color de fondo de la barra de herramientas](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=es)
Diseños y estilos de RRO
Duración: 15 minutos
En este ejercicio, creará una nueva aplicación similar a la aplicación que creó anteriormente. Esta aplicación permite superponer el diseño. Siga los mismos pasos que antes o modifique su aplicación existente.
Asegúrese de agregar las siguientes líneas 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>
Asegúrese de que
activity_main.xml
aparezca de la siguiente manera:<?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>
En su aplicación RRO, cree un
res/layout/activity_main.xml
y agregue lo siguiente:<?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>
Actualice
res/values/styles.xml
para agregar nuestro estilo 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>
Cambie el
targetName
enAndroidManifest.xml
para que apunte al nombre de su nueva aplicación:… android:targetName="CarUiCodelab" …
Agregue los recursos al archivo
sample_overlay.xml
en su 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>
Cree e instale la aplicación y RRO de la misma manera que antes (botón verde Reproducir ). Asegúrese de habilitar su RRO.
La aplicación y RRO se representan de la siguiente manera. El texto Hello World RRO es verde y está centrado como se especifica en el diseño RRO.
![Hola mundo RRO](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=es)
Agregue CarUiRecyclerView a su aplicación
Duración: 15 minutos
La interfaz CarUiRecyclerView
proporciona API para acceder a un RecyclerView
personalizado a través de recursos car-ui-lib
. Por ejemplo, CarUiRecyclerView
verifica una bandera en tiempo de ejecución para determinar si la barra de desplazamiento debe habilitarse o no y selecciona el diseño correspondiente.
![CarUiRecyclerVerContenedor](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=es)
Para agregar un
CarUiRecyclerView
, agréguelo a sus archivosactivity_main.xml
yMainActivity.java
. Puede crear una nueva aplicación desde cero o modificar la aplicación existente. Si modifica la aplicación existente, asegúrese de eliminar los recursos no declarados 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"/>
Puede aparecer el siguiente error, que puedes ignorar:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Siempre que su clase esté escrita correctamente y haya agregado
car-ui-lib
como dependencia, puede crear y compilar su apk. Para eliminar el error, seleccione Archivo > Invalidar cachés y luego haga clic en Invalidar y reiniciar.Agregue lo siguiente 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; }
Cree e instale su aplicación como antes.
Ahora verá un CarUiRecyclerView
:
![CocheUiRecyclerVer](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=es)
Utilice un RRO para eliminar la barra de desplazamiento
Duración: 10 minutos
Este ejercicio le muestra cómo utilizar un RRO para eliminar la barra de desplazamiento de CarUiRecyclerView
.
En su RRO, agregue y modifique los siguientes archivos:
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>
El recurso
car_ui_scrollbar_enable
es un recurso booleanocar-ui-lib
, que controla si la barra de desplazamiento optimizada del automóvil con los botones Arriba y Abajo enCarUiRecyclerView
está presente o no. Cuando se establece enfalse
,CarUiRecyclerView
actúa como unRecyclerView
de 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>
Cree e instale su aplicación como antes. La barra de desplazamiento ahora se elimina de CarUiRecyclerView
:
![CarUiRecyclerView sin barra de desplazamiento](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=es)
Utilice un diseño para superponer la barra de desplazamiento de CarUiRecyclerView
Duración: 15 minutos
En este ejercicio, modificará el diseño de la barra de desplazamiento CarUiRecyclerView
.
Agregue y modifique los siguientes archivos en su aplicación 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>
Para superponer un archivo de diseño, debe agregar todos los ID y atributos de espacio de nombres al
overlay.xml
de su RRO. Vea los archivos a continuación.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>
Se sugiere examinar cómo interactúan estos archivos.
Para simplificar, las dimensiones y los colores están codificados. Sin embargo, una mejor práctica es declarar estos valores en
dimens.xml
ycolors.xml
o incluso designarlos como archivos de color en la carpetares/color/
. Para obtener más información, consulte Estilo de código Java de AOSP para colaboradores .Cree e instale su aplicación como antes. Ha creado
CarUiRecyclerView
con una barra de desplazamiento azul y rieles grises.
¡Felicidades! Ambas flechas aparecen en la parte inferior de la barra de desplazamiento. Aplicó con éxito un RRO a un archivo de recursos de diseño car-ui-lib
utilizando el sistema de compilación Gradle a través de Android Studio.
![CarUiRecyclerView con una barra de desplazamiento azul con rieles grises](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=es)
Elementos de la lista RRO
Duración: 15 minutos
Hasta este punto, ha aplicado una RRO a los componentes car-ui-lib
utilizando componentes del marco (no AndroidX). Para usar componentes de AndroidX en un RRO, debes agregar las dependencias de ese componente tanto a la aplicación como al RRO build.gradle.
También debe agregar attrs
de ese componente a overlayable.xml
en su aplicación, así como sample_overlay.xml
en su RRO.
Nuestra biblioteca ( car-ui-lib
) usa ConstraintLayout
así como otros componentes de AndroidX, por lo que su overlayable.xml
podría verse así:
<?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>
Cambie el diseño de los elementos de la lista en
CarUiRecyclerView
usandoConstraintLayout
. Agregue o modifique los siguientes archivos en su 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
hace referencia a varios componentes/recursos que no están incluidos como dependencias de la aplicación. Estos son recursoscar-ui-lib
. Puedes solucionar este problema agregandocar-ui-lib
como una dependencia de tu aplicación RRO enapp/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' }
El título y el cuerpo ahora están alineados a la derecha en lugar de a la izquierda.
![Título y cuerpo alineados a la derecha](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=es)
Solo aplicamos un RRO a car-ui-lib
usando componentes de AndroidX ( ConstraintLayout
) cuando sus atributos estaban presentes en el archivo car-ui-lib
llamado overlayable.xml
así como en el RRO sample_overlay.xml
. Es posible hacer algo similar en tu propia aplicación. Simplemente agregue todos los attrs
correspondientes al overlayable.xml
de su aplicación, similar a car-ui-lib
.
Sin embargo, no es posible realizar RRO en una aplicación que utiliza componentes de AndroidX cuando la aplicación tiene car-ui-lib
como dependencia en su build.gradle
(cuando la aplicación usa componentes car-ui-lib
). Dado que las asignaciones de atributos ya estaban definidas en overlayable.xml
de la biblioteca car-ui-lib
, agregarlas al overlayable.xml
de su aplicación con car-ui-lib
como dependencia causaría un error mergeDebugResources
como el que se muestra a continuación. Esto se debe a que estos atributos están presentes en varios archivos overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'