Use a biblioteca car-ui-lib
para iniciar sistemas de infoentretenimento (IVI) autoconsistentes no veículo. Este codelab apresenta car-ui-lib
e como usar sobreposições de recursos de tempo de execução (RROs) para personalizar componentes na biblioteca.
O que você aprenderá
Como:
- Inclua componentes
car-ui-lib
em seu aplicativo Android. - Use Gradle para criar aplicativos Android e RROs.
- Use RROs com
car-ui-lib
.
Este codelab não detalha como funcionam os RROs. Consulte Alterar o valor dos recursos de um aplicativo em tempo de execução e Solucionar problemas de sobreposições de recursos de tempo de execução para saber mais.
Antes que você comece
Pré-requisitos
Antes de começar, certifique-se de ter:
Computador com linha de comando (máquina Linux, Mac ou máquina Windows com subsistema Windows para Linux).
Dispositivo Android ou emulador conectado à sua máquina. Consulte Baixar a fonte do Android e Construir o Android .
Conhecimento básico de RROs.
Crie um novo aplicativo Android
Duração: 15 minutos
Nesta seção, você cria um novo projeto do Android Studio.
No Android Studio, crie um aplicativo com um
EmptyActivity
.Figura 1. Crie uma atividade vazia Nomeie o aplicativo
CarUiCodelab
e selecione a linguagem Java. Você também pode selecionar um local de arquivo, se desejar. Aceite os valores padrão para as configurações restantes.Figura 2. Nomeie seu aplicativo Substitua
activity_main.xml
pelo seguinte bloco 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 bloco de código exibe a string
sample_text
, que não está definida.Adicione a string de recurso
sample_text
e defina-a como "Hello World!" no seu arquivostrings.xml
. Para abrir este arquivo, selecione 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>
Para construir seu aplicativo, clique no botão verde Play no canto superior direito. Fazer isso instala automaticamente o apk em seu emulador ou dispositivo Android por meio do Gradle.
O novo aplicativo deve abrir automaticamente no seu emulador ou dispositivo Android. Caso contrário, abra o aplicativo CarUiCodelab
no inicializador de aplicativos, que agora está instalado. Parece assim:
![Abra o novo aplicativo CarUiCodelab](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=pt)
Adicione car-ui-lib ao seu aplicativo Android
Duração: 15 minutos
Adicione car-ui-lib
ao seu aplicativo:
Para adicionar a dependência
car-ui-lib
ao arquivobuild.gradle
do seu projeto, selecione app > build.gradle . Suas dependências devem aparecer assim: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' }
Use componentes car-ui-lib em seu aplicativo Android
Agora que você tem car-ui-lib
, adicione uma barra de ferramentas ao seu aplicativo.
Em seu arquivo
MainActivity.java
, substitua o 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); }
Certifique-se de importar
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Para usar o tema
Theme.CarUi.WithToolbar
, selecione app > src > main > AndroidManifest.xml e atualizeAndroidManifest.xml
para aparecer da seguinte forma:<?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 construir o aplicativo, pressione o botão verde Play como antes.
Adicione RROs ao seu aplicativo
Duração: 30 minutos
Se você estiver familiarizado com RROs, vá para a próxima seção, Adicione um controlador de permissão ao seu aplicativo . Caso contrário, para aprender os conceitos básicos de RROs, consulte Alterar o valor dos recursos de um aplicativo em tempo de execução .
Adicione um controlador de permissão ao seu aplicativo
Para controlar quais recursos um pacote RRO sobrepõe, adicione um arquivo chamado overlayable.xml
à pasta /res
do seu aplicativo. Este arquivo serve como um controlador de permissão entre seu aplicativo (o target ) e seu pacote RRO (o overlay ).
Adicione
res/values/overlayable.xml
ao seu aplicativo e copie o seguinte conteúdo no seu arquivo:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Como a string
sample_text
deve ser sobreposta por um RRO, inclua o nome do recurso no overlayable.xml do aplicativo.Seu arquivo
overlayable.xml
DEVE residir emres/values/
. Caso contrário, oOverlayManagerService
não poderá localizá-lo.Para saber mais sobre recursos sobrepostos e como eles podem ser configurados, consulte Restringir recursos sobrepostos .
Crie um pacote RRO
Nesta seção, você cria um pacote RRO para alterar a string exibida acima de "Hello World!" para "Olá Mundo RRO".
Para criar um novo projeto, selecione Arquivo > Novo > Novo Projeto . Certifique-se de selecionar Nenhuma atividade em vez de Atividade vazia, pois os pacotes RRO contêm apenas recursos.
Suas configurações aparecem de forma semelhante às ilustradas abaixo. O local onde eles são salvos pode ser diferente:
Depois de criar o novo projeto
CarUiRRO
, declare o projeto como um 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>
Fazer isso cria um erro com
@xml/sample_overlay
. O arquivoresourcesMap
mapeia nomes de recursos do pacote de destino para o pacote RRO.Copie o seguinte bloco de código em
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Adicione
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 construir seu alvo RRO, pressione o botão verde Play para criar uma versão Gradle de seu RRO em seu emulador ou dispositivo Android.
Para verificar se seu RRO está instalado corretamente, execute:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Este comando exibe informações úteis sobre o estado dos pacotes RRO no sistema.
-
[ ]
designa que o RRO está instalado e pronto para ser ativado. -
---
indica que o RRO está instalado, mas contém erros. -
[X]
significa que o RRO está instalado e ativado.
Se o seu RRO contiver erros, consulte Solucionar problemas de sobreposições de recursos de tempo de execução antes de continuar.
-
Para ativar o RRO e verificar se ele está ativado:
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
Seu aplicativo exibe a string “Hello World RRO”.
![Olá mundo RRO!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=pt)
Parabéns! Você criou seu primeiro RRO.
Ao usar RROs, você pode usar os sinalizadores --no-resource-deduping
e --no-resource-removal
do Android Asset Packaging Tool (AAPT2) descritos em Opções de link . Não é necessário adicionar sinalizações neste codelab, mas sugerimos que você as use em seus RROs para evitar a remoção de recursos (e dores de cabeça de depuração). Você pode adicioná-los ao arquivo build.gradle
do seu RRO assim:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Para saber mais sobre esses sinalizadores, consulte Construir o pacote e AAPT2 .
Modifique componentes car-ui-lib
usando RROs em seu aplicativo Android
Esta página descreve como você pode usar uma sobreposição de recursos de tempo de execução (RRO) para modificar componentes da biblioteca car-ui-lib
em seu aplicativo Android.
Defina a cor de fundo da barra de ferramentas
Duração: 15 minutos
Para alterar a cor de fundo da barra de ferramentas:
Adicione o seguinte valor ao seu aplicativo RRO e defina o recurso como verde brilhante (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
A biblioteca
car-ui-lib
contém um recurso chamadocar_ui_toolbar_background
. Quando este recurso está contido na configuração de um RRO, a barra de ferramentas não muda porque o valor errado é direcionado.No
AndroidManifest.xml
do seu RRO, atualizetargetName
para apontar paracar-ui-lib
:… android:targetName="car-ui-lib" …
Você DEVE criar um novo pacote RRO para cada pacote de destino que deseja RRO. Por exemplo, ao criar sobreposições para dois destinos diferentes, você deve criar dois apks de sobreposição.
Crie, verifique, instale e ative o RRO da mesma forma que antes.
Seu aplicativo aparece assim:
![Nova cor de fundo da barra de ferramentas](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=pt)
Layouts e estilos RRO
Duração: 15 minutos
Neste exercício, você criará um novo aplicativo semelhante ao aplicativo criado anteriormente. Este aplicativo permite que o layout seja sobreposto. Siga as mesmas etapas anteriores ou modifique seu aplicativo existente.
Certifique-se de adicionar as seguintes linhas ao
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>
Certifique-se de que
activity_main.xml
apareça da seguinte forma:<?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>
Em seu aplicativo RRO, crie um
res/layout/activity_main.xml
e adicione o seguinte:<?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>
Atualize
res/values/styles.xml
para adicionar nosso estilo ao 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>
Altere
targetName
emAndroidManifest.xml
para apontar para o nome do seu novo aplicativo:… android:targetName="CarUiCodelab" …
Adicione os recursos ao arquivo
sample_overlay.xml
em seu 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>
Crie e instale o aplicativo e o RRO da mesma forma que antes (botão verde Play ). Certifique-se de habilitar seu RRO.
O aplicativo e o RRO são renderizados da seguinte maneira. O texto Hello World RRO é verde e centralizado conforme especificado no layout RRO.
![Olá mundo RRO](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=pt)
Adicione CarUiRecyclerView ao seu aplicativo
Duração: 15 minutos
A interface CarUiRecyclerView
fornece APIs para acessar um RecyclerView
personalizado por meio de recursos car-ui-lib
. Por exemplo, CarUiRecyclerView
verifica um sinalizador em tempo de execução para determinar se a barra de rolagem deve ser habilitada ou não e seleciona o layout correspondente.
![CarUiRecyclerViewContainer](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=pt)
Para adicionar um
CarUiRecyclerView
, adicione-o aos seus arquivosactivity_main.xml
eMainActivity.java
. Você pode criar um novo aplicativo do zero ou modificar o aplicativo existente. Se você modificar o aplicativo existente, remova os recursos não 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"/>
O seguinte erro pode aparecer, que você pode ignorar:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Contanto que sua classe esteja escrita corretamente e você tenha adicionado
car-ui-lib
como uma dependência, você pode construir e compilar seu apk. Para remover o erro, selecione Arquivo > Invalidar Caches e clique em Invalidar e Reiniciar.Adicione o seguinte ao
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; }
Crie e instale seu aplicativo como antes.
Agora você vê um CarUiRecyclerView
:
![CarUiRecyclerView](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=pt)
Use um RRO para remover a barra de rolagem
Duração: 10 minutos
Este exercício mostra como usar um RRO para remover a barra de rolagem de CarUiRecyclerView
.
No seu RRO, adicione e modifique os seguintes arquivos:
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>
O recurso
car_ui_scrollbar_enable
é um recurso booleanocar-ui-lib
, que controla se a barra de rolagem otimizada para carro com botões para cima e para baixo emCarUiRecyclerView
está presente ou não. Quando definido comofalse
,CarUiRecyclerView
atua como um 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>
Crie e instale seu aplicativo como antes. A barra de rolagem agora foi removida de CarUiRecyclerView
:
![CarUiRecyclerView sem barra de rolagem](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=pt)
Use um layout para sobrepor a barra de rolagem CarUiRecyclerView
Duração: 15 minutos
Neste exercício, você modifica o layout da barra de rolagem CarUiRecyclerView
.
Adicione e modifique os seguintes arquivos em seu aplicativo 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 sobrepor um arquivo de layout, você deve adicionar todos os IDs e atributos de namespace ao
overlay.xml
do seu RRO. Veja os arquivos abaixo.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>
Sugere-se examinar como esses arquivos interagem.
Para simplificar, as dimensões e cores são codificadas. No entanto, uma prática recomendada é declarar esses valores em
dimens.xml
ecolors.xml
ou mesmo designá-los como arquivos de cores na pastares/color/
. Para saber mais, consulte Estilo de código Java AOSP para colaboradores .Crie e instale seu aplicativo como antes. Você construiu
CarUiRecyclerView
com uma barra de rolagem azul e trilhos cinza.
Parabéns! Ambas as setas aparecem na parte inferior da barra de rolagem. Você aplicou com êxito um RRO a um arquivo de recurso de layout car-ui-lib
usando o sistema de compilação Gradle por meio do Android Studio.
![CarUiRecyclerView com uma barra de rolagem azul com trilhos cinza](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=pt)
Itens da lista RRO
Duração: 15 minutos
Até este ponto, você aplicou um RRO aos componentes car-ui-lib
usando componentes de estrutura (não AndroidX). Para usar componentes AndroidX em um RRO, você deve adicionar as dependências desse componente ao aplicativo e ao RRO build.gradle.
Você também deve adicionar attrs
desse componente ao overlayable.xml
no seu aplicativo, bem como ao sample_overlay.xml
no seu RRO.
Nossa biblioteca ( car-ui-lib
) usa ConstraintLayout
, bem como outros componentes do AndroidX, então seu overlayable.xml
pode ficar assim:
<?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>
Altere o layout dos itens da lista no
CarUiRecyclerView
usandoConstraintLayout
. Adicione ou modifique os seguintes arquivos em seu 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
faz referência a vários componentes/recursos que não estão incluídos como dependências do aplicativo. Estes são recursoscar-ui-lib
. Você pode corrigir isso adicionandocar-ui-lib
como uma dependência ao seu aplicativo RRO emapp/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' }
O título e o corpo agora estão alinhados à direita em vez de alinhados à esquerda.
![Título e corpo alinhados à direita](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=pt)
Aplicamos um RRO a car-ui-lib
usando componentes AndroidX ( ConstraintLayout
) apenas quando seus atributos estavam presentes no arquivo car-ui-lib
chamado overlayable.xml
, bem como no RRO sample_overlay.xml
. É possível fazer algo semelhante em seu próprio aplicativo. Basta adicionar todos os attrs
correspondentes ao overlayable.xml
do seu aplicativo, semelhante a car-ui-lib
.
No entanto, não é possível fazer RRO de um aplicativo usando componentes AndroidX quando o aplicativo tem car-ui-lib
como dependência em seu build.gradle
(quando o aplicativo usa componentes car-ui-lib
). Como os mapeamentos de atributos já foram definidos no overlayable.xml
da biblioteca car-ui-lib
, adicioná-los ao overlayable.xml
do seu aplicativo com car-ui-lib
como uma dependência causaria um erro mergeDebugResources
como o abaixo. Isso ocorre porque esses atributos estão presentes em vários arquivos overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'