Use a biblioteca car-ui-lib
para iniciar sistemas de infoentretenimento (IVI) autoconsistentes no veículo. Este codelab apresenta o car-ui-lib
e como você pode usar Runtime Resource Overlays (RROs) para personalizar componentes na biblioteca.
O que você aprenderá
Como:
- Inclua componentes
car-ui-lib
em seu aplicativo Android. - Use o Gradle para criar aplicativos Android e RROs.
- Use RROs com
car-ui-lib
.
Este codelab não detalha como os RROs funcionam. Consulte sobreposições de recursos de tempo de execução (RRO) e solução de 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 Baixando o código-fonte e Construindo o Android .
Conhecimento básico de RROs.
Criar 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 uma
EmptyActivity
.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.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!” em seu arquivostrings.xml
. Para abrir esse 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 criar seu aplicativo, clique no botão verde Reproduzir 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 em seu emulador ou dispositivo Android. Caso contrário, abra o aplicativo CarUiCodelab
no iniciador de aplicativos, que agora está instalado. Aparece assim:
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
, sobrescreva 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 criar o aplicativo, pressione o botão verde Reproduzir como antes.
Adicione RROs ao seu aplicativo
Duração: 30 minutos
Se você estiver familiarizado com sobreposições de recursos de tempo de execução (RROs), vá para a próxima seção, Adicionar um controlador de permissão ao seu aplicativo . Caso contrário, para aprender os fundamentos dos 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 alvo ) e seu pacote RRO (o overlay ).
Adicione
res/values/overlayable.xml
ao seu aplicativo e copie o seguinte conteúdo em 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 que podem ser sobrepostos e como eles podem ser configurados, consulte Restringindo recursos que podem ser sobrepostos .
Criar 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 Sem atividade em vez de Atividade vazia, pois os pacotes RRO contêm apenas recursos.
Suas configurações são semelhantes à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 criar seu destino RRO, pressione o botão verde Reproduzir para criar uma compilação Gradle de seu RRO em seu emulador ou dispositivo Android.
Para verificar se o 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 Solução de problemas de sobreposições de recursos de tempo de execução antes de continuar.
-
Para habilitar o RRO e verificar se ele 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
Seu aplicativo exibe a string "Hello World RRO".
Parabéns! Você criou seu primeiro RRO.
Ao usar RROs, convém usar os sinalizadores da Android Asset Packaging Tool (AAPT2) --no-resource-deduping
e --no-resource-removal
descritos em Opções de link . Não é necessário adicionar os sinalizadores neste codelab, mas sugerimos que você os use em seus RROs para evitar a remoção de recursos (e dores de cabeça com 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 Construindo o pacote e AAPT2 .
Modifique os 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.
Definir 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 denominadocar_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
para 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.
Construa, verifique, instale e habilite o RRO da mesma forma que antes.
Seu aplicativo aparece assim:
Layouts e estilos RRO
Duração: 15 minutos
Neste exercício, você cria um novo aplicativo semelhante ao aplicativo criado anteriormente. Este aplicativo permite que o layout seja sobreposto. Siga as mesmas etapas de antes 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
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 o
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 Reproduzir ). 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.
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.
Para adicionar um
CarUiRecyclerView
, adicione-o aos arquivosactivity_main.xml
eMainActivity.java
. Você pode criar um novo aplicativo do zero ou modificar o aplicativo existente. Se você modificar o aplicativo existente, certifique-se de remover 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 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 seu aplicativo como antes.
Agora você vê um CarUiRecyclerView
:
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 do carro com botões para cima e para baixo noCarUiRecyclerView
está presente ou não. Quando definido comofalse
,CarUiRecyclerView
age 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 do CarUiRecyclerView
:
Use um layout para sobrepor a barra de rolagem CarUiRecyclerView
Duração: 15 minutos
Neste exercício, você modificará 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
de 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 até 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.
Itens da lista de 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 do 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 a overlayable.xml
em seu aplicativo, bem como o sample_overlay.xml
em seu RRO.
Nossa biblioteca ( car-ui-lib
) usa ConstraintLayout
, bem como outros componentes do AndroidX, então seu overlayable.xml
pode ter esta aparência:
<?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árias referências 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.
Apenas aplicamos um RRO a car-ui-lib
usando componentes AndroidX ( ConstraintLayout
) quando seus atributos estavam presentes no arquivo car-ui-lib
denominado 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 RRO de um aplicativo usando componentes AndroidX quando o aplicativo tem car-ui-lib
como uma 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'