Use a biblioteca car-ui-lib
para iniciar um infoentretenimento próprio, no veículo
(IVI). Este codelab apresenta o car-ui-lib
e como você pode
usar sobreposições de recursos no ambiente de execução (RROs, na sigla em inglês) para personalizar componentes na biblioteca.
O que você vai aprender
Como:
- Inclua componentes
car-ui-lib
no seu app Android. - Use o Gradle para criar apps Android e RROs.
- Use RROs com
car-ui-lib
.
Este codelab não detalha como as RROs funcionam. Consulte Mudar o valor dos recursos de um app no momento da execução e Resolver problemas de sobreposições de recursos no momento da execução para saber mais.
Antes de começar
Pré-requisitos
Antes de começar, verifique se você:
Computador com linha de comando (máquina Linux, Mac ou Windows com Windows Subsystem para Linux).
Dispositivo ou emulador Android conectado à máquina. Consulte Faça o download da origem do Android e Crie para o Android.
Conhecimento básico de RROs.
Criar um novo app Android
Duração: 15 minutos
Nesta seção, você vai criar um novo projeto do Android Studio.
No Android Studio, crie um app com uma
EmptyActivity
.Figura 1.Criar uma atividade vazia Nomeie o app como
CarUiCodelab
e selecione a linguagem Java. Você pode selecione também o local do arquivo, se quiser. Aceite os valores padrão do campo configurações restantes.Figura 2. Dê um nome ao app 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>
Esse bloco de código mostra a string
sample_text
, que não está definida.Adicione a string de recurso
sample_text
e a defina como "Hello World!" no seu arquivostrings.xml
. Para abrir esse arquivo, selecione app > src > principal > res > valores > strings.xml padrão.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
Para criar seu app, clique no botão verde Play no canto superior direito. Ao fazer isso instala automaticamente o apk no emulador ou dispositivo Android por meio de Gradle.
O novo app será aberto automaticamente no emulador ou dispositivo Android. Se
Não, abra o app CarUiCodelab
no Acesso rápido aos apps, que agora está instalado.
Ela aparece assim:
![Abrir o novo app CarUiCodelab](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=pt-br)
Adicionar car-ui-lib ao app Android
Duração: 15 minutos
Adicione car-ui-lib
ao app:
Para adicionar a dependência
car-ui-lib
ao arquivobuild.gradle
do projeto, faça o seguinte: selecione aplicativo > build.gradle. Suas dependências vão ficar 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' }
Usar componentes car-ui-lib no app Android
Agora que você tem o car-ui-lib
, adicione uma barra de ferramentas ao app.
No 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); }
Importe
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 atualizarAndroidManifest.xml
apareça 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 criar o app, pressione o botão verde Play como antes.
Adicionar RROs ao seu app
Duração: 30 minutos
Se você já conhece as RROs, acesse a próxima seção Adicionar um controlador de permissões ao app. Caso contrário, para aprender o básico sobre RROs, consulte Mudar o valor dos recursos de um app durante a execução.
Adicionar um controlador de permissões ao app
Para controlar a quais recursos um pacote RRO se sobrepõe, adicione um arquivo chamado
overlayable.xml
à pasta /res
do app. Este arquivo serve como uma permissão
entre seu app (o destino) e seu pacote RRO (a sobreposição).
Adicione
res/values/overlayable.xml
ao app 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
precisa ser sobreposta por uma RRO, inclua o o nome do recurso no overlayable.xml do app.Seu arquivo
overlayable.xml
PRECISA residir emres/values/
. Caso contrário, oOverlayManagerService
não conseguiu localizá-lo.Para saber mais sobre recursos sobrepostos e como eles podem ser configurado, consulte Restrição de sobreposição do Google Cloud.
Criar um pacote RRO
Nesta seção, você vai criar um pacote RRO para alterar a string exibida acima em "Hello World!" para "Hello World RRO".
Para criar um novo projeto, selecione File > Novo > Novo projeto. Não se esqueça de Selecione No Activity em vez de Empty Activity, já que os pacotes RRO contêm apenas recursos.
Suas configurações são parecidas com as ilustradas abaixo. A O local em que eles são salvos pode ser diferente:
Depois de criar o novo projeto
CarUiRRO
, declare-o 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>
Isso cria um erro com
@xml/sample_overlay
. OresourcesMap
O arquivo mapeia nomes de recursos do pacote de destino para o pacote RRO.Copie o seguinte bloco de código para
…/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 criar o destino RRO, pressione o botão verde Play para criar um da RRO no emulador ou dispositivo Android.
Para verificar se a RRO está instalada corretamente, execute:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Esse comando exibe informações úteis sobre o estado dos pacotes RRO no sistema.
[ ]
designa que a RRO está instalada e pronta para ser ativada.---
indica que a RRO está instalada, mas contém erros.[X]
significa que a RRO está instalada e ativada.
Se a RRO tiver erros, consulte Resolver problemas de sobreposições de recursos no momento da execução antes de continuar.
Para ativar a RRO e verificar se ela está ativada:
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
O app mostra a string "Hello World RRO".
![Hello World RRO!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=pt-br)
Parabéns! Você criou sua primeira RRO.
Ao usar RROs, você pode usar a Android Asset Packaging Tool (AAPT2)
as sinalizações --no-resource-deduping
e --no-resource-removal
descritas
Opções de link.
Não é necessário adicionar as flags neste codelab, mas sugerimos que elas sejam usadas.
nas RROs para evitar a remoção de recursos (e depurar dores de cabeça). Você
pode adicioná-las ao arquivo build.gradle
da RRO desta forma:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Para saber mais sobre essas sinalizações, consulte Crie o pacote e AAPT2:
Modificar componentes car-ui-lib
usando RROs no seu app Android
Esta página descreve como usar uma sobreposição de recursos no ambiente de execução (RRO) para
modificar componentes da biblioteca car-ui-lib
no seu app Android;
Definir a cor do plano 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 app RRO e defina o recurso como "brilhante". verde (
#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 esse recurso está contido no configuração de uma RRO, a barra de ferramentas não muda porque o valor errado está segmentado.No
AndroidManifest.xml
da sua RRO, atualizetargetName
para apontar paracar-ui-lib
:… android:targetName="car-ui-lib" …
É NECESSÁRIO criar um novo pacote de RRO para cada pacote de destino que você quiser RRO. Por exemplo, ao criar sobreposições para dois destinos diferentes, você deve criar dois APKs de sobreposição.
Crie, verifique, instale e ative a RRO da mesma forma que antes.
Seu app aparece assim:
![Nova cor de plano de fundo da Barra de Ferramentas Google](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=pt-br)
Layouts e estilos de RRO
Duração: 15 minutos
Neste exercício, você criará um novo aplicativo semelhante ao aplicativo criado anteriormente. Isso permite que o layout seja sobreposto. Siga as mesmas etapas anteriores ou modifique seu app atual.
Adicione as seguintes linhas 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>
Verifique se
activity_main.xml
aparece da seguinte maneira:<?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>
No app 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 o
res/values/styles.xml
para adicionar nosso estilo à 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>
Mude o
targetName
emAndroidManifest.xml
para apontar para o nome do seu novo app:… android:targetName="CarUiCodelab" …
Adicione os recursos ao arquivo
sample_overlay.xml
na sua 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 app e a RRO da mesma forma de antes (Play verde ). Ative a RRO.
O app e a RRO são renderizados desta forma. O texto de RRO "Hello World" é verde e centralizada conforme especificado na RRO do layout.
![RRO "Hello World"](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=pt-br)
Adicionar o CarUiRecyclerView ao app
Duração: 15 minutos
A interface CarUiRecyclerView
fornece APIs para acessar um RecyclerView
personalizado pelos recursos car-ui-lib
. Por exemplo, CarUiRecyclerView
.
verifica uma flag durante a execução para determinar se a barra de rolagem deve ser ativada ou não
e seleciona o layout correspondente.
![Contêiner do CarUiRecyclerView](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=pt-br)
Para adicionar um
CarUiRecyclerView
, adicione-o aactivity_main.xml
eMainActivity.java
. É possível criar um novo app do zero ou modificar o aplicativo existente. Se você modificar o app atual, remova-o 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"/>
Ignore o seguinte erro:
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 compilar e compilar o seu apk. Para remover o erro, selecione Arquivo > Invalide os caches e clique em Invalidar e reiniciar.Adicione o seguinte 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; }
Crie e instale o app como antes.
Agora você verá um CarUiRecyclerView
:
![CarUiRecyclerView](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=pt-br)
Usar uma RRO para remover a barra de rolagem
Duração: 10 minutos
Este exercício mostra como usar uma RRO para remover a barra de rolagem
CarUiRecyclerView
:
Na 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 carros com botões para cima e para baixo emCarUiRecyclerView
está presente ou não. Quando definido comofalse
, OCarUiRecyclerView
atua como umRecyclerView
do 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>
Crie e instale o app como antes. A barra de rolagem foi removida dos
CarUiRecyclerView
:
![CarUiRecyclerView sem barra de rolagem](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=pt-br)
Usar um layout para sobrepor a barra de rolagem CarUiRecyclerView
Duração: 15 minutos
Neste exercício, você vai modificar o layout da barra de rolagem do CarUiRecyclerView
.
Adicione e modifique os seguintes arquivos no 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>
Para sobrepor um arquivo de layout, adicione todos os IDs e os namespaces atributos ao
overlay.xml
da RRO. Confira 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>
Sugerimos analisar como esses arquivos interagem.
Para simplificar, as dimensões e as cores são fixadas no código. No entanto, uma melhor a prática é declarar esses valores em
dimens.xml
ecolors.xml
ou até designados como arquivos de cor na pastares/color/
. Para saber mais, ver Estilo de código Java do AOSP para colaboradores.Crie e instale o app como antes. Você criou
CarUiRecyclerView
com uma barra de rolagem azul e colunas cinza.
Parabéns! As duas setas aparecem na parte inferior da barra de rolagem. Você
aplicou uma RRO a um arquivo de recurso de layout car-ui-lib
usando o build do Gradle
pelo Android Studio.
![CarUiRecyclerView com uma barra de rolagem azul com grades cinzas](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=pt-br)
Itens de lista de RRO
Duração: 15 minutos
Até agora, você aplicou uma RRO aos componentes car-ui-lib
usando o framework.
(não do AndroidX). Para usar os componentes do AndroidX em uma RRO, é preciso adicionar
as dependências desse componente para o app e a RRO build.gradle.
Você
também precisa adicionar o attrs
do componente ao overlayable.xml
no app.
como o sample_overlay.xml
na RRO.
Nossa biblioteca (car-ui-lib
) usa ConstraintLayout
, assim como outras versões do AndroidX
então o overlayable.xml
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>
Mude o layout dos itens da lista no
CarUiRecyclerView
usando oConstraintLayout
. Adicione ou modifique os seguintes arquivos na sua 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árias referências a vários componentes/ recursos que não estão incluídos como dependências do app. Estes são os recursos decar-ui-lib
. Para corrigir isso, adicionecar-ui-lib
como uma dependência do seu app 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 à esquerda.
![Título e corpo alinhados à direita](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=pt-br)
Aplicamos apenas uma RRO ao car-ui-lib
usando componentes do AndroidX
(ConstraintLayout
) quando os atributos estavam presentes no car-ui-lib
arquivo chamado overlayable.xml
, bem como o RRO sample_overlay.xml
. Está
fazer algo semelhante no seu próprio app. Basta adicionar todas as
attrs
ao overlayable.xml
do app, semelhante a car-ui-lib
.
No entanto, não é possível fazer a RRO de um app usando componentes do AndroidX ao
o app tem car-ui-lib
como uma dependência em build.gradle
(quando o app usa
car-ui-lib
). Como os mapeamentos de atributos já estavam definidos no
o arquivo overlayable.xml
da biblioteca car-ui-lib
, adicionando-o à sua
overlayable.xml
do app com car-ui-lib
como dependência causaria uma
mergeDebugResources
como esse 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'