Используйте библиотеку car-ui-lib
для запуска самосогласованных автомобильных информационно-развлекательных систем (IVI). В этой лаборатории кода вы познакомитесь с car-ui-lib
и узнаете, как можно использовать наложения ресурсов времени выполнения (RRO) для настройки компонентов в библиотеке.
Что вы узнаете
Как:
- Включите компоненты
car-ui-lib
в свое приложение для Android. - Используйте Gradle для создания приложений Android и RRO.
- Используйте RRO с
car-ui-lib
.
В этой кодовой лаборатории не описывается, как работают RRO. Дополнительные сведения см. в разделах Изменение значения ресурсов приложения во время выполнения и Устранение неполадок с наложением ресурсов во время выполнения .
Прежде чем начать
Предварительные условия
Прежде чем начать, убедитесь, что у вас есть:
Компьютер с командной строкой (компьютер с Linux, Mac или компьютер с Windows с подсистемой Windows для Linux).
Устройство Android или эмулятор, подключенный к вашему компьютеру. См. раздел «Загрузка исходного кода Android и сборка Android» .
Базовые знания РРО.
Создайте новое приложение для Android
Продолжительность: 15 минут
В этом разделе вы создадите новый проект Android Studio.
В Android Studio создайте приложение с
EmptyActivity
.Рисунок 1. Создание пустого действия Назовите приложение
CarUiCodelab
и выберите язык Java. При желании вы также можете выбрать местоположение файла. Примите значения по умолчанию для остальных настроек.Рисунок 2. Назовите свое приложение Замените
activity_main.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" 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>
Этот блок кода отображает строку
sample_text
, которая не определена.Добавьте строку ресурса
sample_text
и установите для нее значение «Hello World!» в вашем файлеstrings.xml
. Чтобы открыть этот файл, выберите 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>
Чтобы создать свое приложение, нажмите зеленую кнопку «Воспроизвести» в правом верхнем углу. При этом APK автоматически устанавливается на ваш эмулятор или устройство Android через Gradle.
Новое приложение должно автоматически открыться на вашем эмуляторе или устройстве Android. Если нет, откройте приложение CarUiCodelab
из средства запуска приложений, которое теперь установлено. Это выглядит следующим образом:
![Откройте новое приложение CarUiCodelab.](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=ru)
Добавьте car-ui-lib в свое приложение для Android
Продолжительность: 15 минут
Добавьте car-ui-lib
в свое приложение:
Чтобы добавить зависимость
car-ui-lib
в файлbuild.gradle
вашего проекта, выберите app > 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' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' }
Используйте компоненты car-ui-lib в своем приложении для Android.
Теперь, когда у вас есть car-ui-lib
, добавьте панель инструментов в свое приложение.
В файле
MainActivity.java
перезапишите методonCreate
:@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); }
Обязательно импортируйте
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Чтобы использовать тему
Theme.CarUi.WithToolbar
, выберите приложение > src > main > AndroidManifest.xml , а затем обновитеAndroidManifest.xml
, чтобы он выглядел следующим образом:<?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>
Чтобы создать приложение, нажмите зеленую кнопку «Воспроизвести» , как и раньше.
Добавьте RRO в свое приложение
Продолжительность: 30 минут
Если вы знакомы с RRO, перейдите к следующему разделу « Добавление контроллера разрешений в ваше приложение» . В противном случае, чтобы изучить основы RRO, см. Изменение значения ресурсов приложения во время выполнения .
Добавьте контроллер разрешений в свое приложение
Чтобы контролировать, какие ресурсы накладывает пакет RRO, добавьте файл с именем overlayable.xml
в папку /res
вашего приложения. Этот файл служит контроллером разрешений между вашим приложением ( цель ) и вашим пакетом RRO ( оверлей ).
Добавьте
res/values/overlayable.xml
в свое приложение и скопируйте в файл следующий контент:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Поскольку строка
sample_text
должна быть наложена RRO, включите имя ресурса в файл overlayable.xml приложения.Ваш файл
overlayable.xml
ДОЛЖЕН находиться вres/values/
. В противном случаеOverlayManagerService
не сможет его найти.Дополнительные сведения о накладываемых ресурсах и способах их настройки см. в разделе Ограничение накладываемых ресурсов .
Создать пакет RRO
В этом разделе вы создадите пакет RRO, чтобы изменить отображаемую выше строку с «Hello World!» на «Hello World RRO».
Чтобы создать новый проект, выберите «Файл» > «Создать» > «Новый проект» . Обязательно выберите «Нет активности» вместо «Пустое действие», поскольку пакеты RRO содержат только ресурсы.
Ваши конфигурации выглядят аналогично показанным ниже. Местоположение, в котором они сохраняются, может отличаться:
После создания нового проекта
CarUiRRO
объявите его как RRO, изменив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="CarUiCodelab" android:isStatic="false" android:resourcesMap="@xml/sample_overlay" /> </manifest>
Это приведет к ошибке
@xml/sample_overlay
. ФайлresourcesMap
сопоставляет имена ресурсов из целевого пакета с пакетом RRO.Скопируйте следующий блок кода в
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Добавьте
sample_text
в…/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>
Чтобы создать цель RRO, нажмите зеленую кнопку «Воспроизвести» , чтобы создать сборку Gradle вашего RRO на вашем эмуляторе или устройстве Android.
Чтобы убедиться, что ваш RRO установлен правильно, запустите:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Эта команда отображает полезную информацию о состоянии пакетов RRO в системе.
-
[ ]
означает, что RRO установлен и готов к активации. -
---
указывает, что RRO установлен, но содержит ошибки. -
[X]
означает, что RRO установлен и активирован.
Если ваш RRO содержит ошибки, прежде чем продолжить, ознакомьтесь со статьей Устранение неполадок с наложениями ресурсов среды выполнения .
-
Чтобы включить RRO и убедиться, что он включен:
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
Ваше приложение отображает строку «Hello World RRO».
![Привет, мир РРО!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=ru)
Поздравляем! Вы создали свой первый RRO.
При использовании RRO вы можете использовать флаги Android Asset Packaging Tool (AAPT2) --no-resource-deduping
и --no-resource-removal
, описанные в разделе «Параметры ссылки» . Нет необходимости добавлять флаги в эту кодовую лабораторию, но мы предлагаем вам использовать их в своих RRO, чтобы избежать удаления ресурсов (и головной боли при отладке). Вы можете добавить их в файл build.gradle
вашего RRO следующим образом:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Дополнительные сведения об этих флагах см. в разделе Сборка пакета и AAPT2 .
Измените компоненты car-ui-lib
с помощью RRO в своем приложении для Android.
На этой странице описано, как можно использовать наложение ресурсов времени выполнения (RRO) для изменения компонентов из библиотеки car-ui-lib
в вашем приложении Android.
Установить цвет фона панели инструментов
Продолжительность: 15 минут
Чтобы изменить цвет фона панели инструментов:
Добавьте следующее значение в свое приложение RRO и установите для ресурса ярко-зеленый цвет (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
Библиотека
car-ui-lib
содержит ресурс с именемcar_ui_toolbar_background
. Если этот ресурс содержится в конфигурации RRO, панель инструментов не меняется, поскольку задано неправильное значение.В
AndroidManifest.xml
для вашего RRO обновитеtargetName
, чтобы он указывал наcar-ui-lib
:… android:targetName="car-ui-lib" …
Вы ДОЛЖНЫ создать новый пакет RRO для каждого целевого пакета, который вы хотите использовать в RRO. Например, при создании наложений для двух разных целей необходимо создать два APK-наложения.
Создайте, проверьте, установите и включите RRO так же, как и раньше.
Ваше приложение выглядит следующим образом:
![Новый цвет фона панели инструментов](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=ru)
Макеты и стили RRO
Продолжительность: 15 минут
В этом упражнении вы создадите новое приложение, аналогичное приложению, которое вы создали ранее. Это приложение позволяет накладывать макет. Выполните те же действия, что и раньше, или измените существующее приложение.
Обязательно добавьте следующие строки в
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>
Убедитесь, что
activity_main.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" 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>
В своем приложении RRO создайте
res/layout/activity_main.xml
и добавьте следующее:<?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>
Обновите
res/values/styles.xml
, чтобы добавить наш стиль в 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>
Измените
targetName
вAndroidManifest.xml
, чтобы оно указывало на имя вашего нового приложения:… android:targetName="CarUiCodelab" …
Добавьте ресурсы в файл
sample_overlay.xml
в вашем 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>
Создайте и установите приложение и RRO так же, как и раньше (зеленая кнопка «Воспроизвести» ). Обязательно включите свой RRO.
Приложение и RRO визуализируются следующим образом. Текст RRO Hello World имеет зеленый цвет и центрируется, как указано в макете RRO.
![Привет, мир, РРО](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=ru)
Добавьте CarUiRecyclerView в свое приложение.
Продолжительность: 15 минут
Интерфейс CarUiRecyclerView
предоставляет API для доступа к RecyclerView
, настроенному с помощью ресурсов car-ui-lib
. Например, CarUiRecyclerView
проверяет флаг во время выполнения, чтобы определить, следует ли включать полосу прокрутки или нет, и выбирает соответствующий макет.
![CarUiRecyclerViewContainer](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=ru)
Чтобы добавить
CarUiRecyclerView
, добавьте его в файлыactivity_main.xml
иMainActivity.java
. Вы можете создать новое приложение с нуля или изменить существующее приложение. Если вы изменяете существующее приложение, обязательно удалите необъявленные ресурсы изoverlayable.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"/>
Может появиться следующая ошибка, которую можно игнорировать:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Если ваш класс написан правильно и вы добавили
car-ui-lib
в качестве зависимости, вы можете собрать и скомпилировать свой APK. Чтобы удалить ошибку, выберите «Файл» > «Недействительные кэши», затем нажмите «Недействительно и перезапустить».Добавьте следующее в
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; }
Создайте и установите свое приложение, как и раньше.
Теперь вы видите CarUiRecyclerView
:
![АвтомобильUiRecyclerПросмотр](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=ru)
Используйте RRO, чтобы удалить полосу прокрутки
Продолжительность: 10 минут
В этом упражнении показано, как использовать RRO для удаления полосы прокрутки из CarUiRecyclerView
.
В вашем RRO добавьте и измените следующие файлы:
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>
Ресурс
car_ui_scrollbar_enable
— это логический ресурсcar-ui-lib
, который контролирует, присутствует ли оптимизированная для автомобиля полоса прокрутки с кнопками вверх и вниз вCarUiRecyclerView
или нет. Если установлено значениеfalse
,CarUiRecyclerView
действует как 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>
Создайте и установите свое приложение, как и раньше. Полоса прокрутки теперь удалена из CarUiRecyclerView
:
![CarUiRecyclerView без полосы прокрутки](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=ru)
Используйте макет для наложения полосы прокрутки CarUiRecyclerView.
Продолжительность: 15 минут
В этом упражнении вы измените макет полосы прокрутки CarUiRecyclerView
.
Добавьте и измените следующие файлы в своем приложении 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>
Чтобы наложить файл макета, необходимо добавить все идентификаторы и атрибуты пространства имен в файл
overlay.xml
вашего RRO. Смотрите файлы ниже.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>
Предлагается изучить, как взаимодействуют эти файлы.
Для простоты размеры и цвета жестко запрограммированы. Однако лучше всего объявлять эти значения в
dimens.xml
иcolors.xml
или даже обозначать их как файлы цветов в папкеres/color/
. Дополнительные сведения см. в разделе Стиль кода Java AOSP для участников .Создайте и установите свое приложение, как и раньше. Вы создали
CarUiRecyclerView
с синей полосой прокрутки и серыми полосами.
Поздравляем! Обе стрелки появляются в нижней части полосы прокрутки. Вы успешно применили RRO к файлу ресурсов макета car-ui-lib
с помощью системы сборки Gradle через Android Studio.
![CarUiRecyclerView с синей полосой прокрутки с серыми полосами](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=ru)
РРО Элементы списка
Продолжительность: 15 минут
К этому моменту вы применили RRO к компонентам car-ui-lib
используя компоненты платформы (не AndroidX). Чтобы использовать компоненты AndroidX в RRO, необходимо добавить зависимости этого компонента как в приложение, так и в RRO build.gradle.
Вы также должны добавить attrs
этого компонента в overlayable.xml
вашего приложения, а также sample_overlay.xml
в вашем RRO.
Наша библиотека ( car-ui-lib
) использует ConstraintLayout
, а также другие компоненты AndroidX, поэтому ее overlayable.xml
может выглядеть так:
<?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>
Измените макет элементов списка в
CarUiRecyclerView
с помощьюConstraintLayout
. Добавьте или измените следующие файлы в вашем 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
ссылается на несколько ссылок на несколько компонентов/ресурсов, которые не включены в качестве зависимостей приложения. Это ресурсыcar-ui-lib
. Вы можете исправить это, добавивcar-ui-lib
в качестве зависимости к вашему приложению RRO вapp/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' }
Заголовок и текст теперь выравниваются по правому краю, а не по левому.
![Заголовок и текст с выравниванием по правому краю](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=ru)
Мы применяли RRO к car-ui-lib
с использованием компонентов AndroidX ( ConstraintLayout
), только если его атрибуты присутствовали в файле car-ui-lib
с именем overlayable.xml
, а также в RRO sample_overlay.xml
. Нечто подобное можно сделать и в своем приложении. Просто добавьте все соответствующие attrs
в overlayable.xml
вашего приложения, аналогично car-ui-lib
.
Однако невозможно выполнить RRO для приложения с использованием компонентов AndroidX, если приложение имеет car-ui-lib
в качестве зависимости в своем build.gradle
(когда приложение использует компоненты car-ui-lib
). Поскольку сопоставления атрибутов уже определены в файле overlayable.xml
библиотеки car-ui-lib
, добавление их в overlayable.xml
вашего приложения с использованием car-ui-lib
в качестве зависимости приведет к ошибке mergeDebugResources
, подобной приведенной ниже. Это связано с тем, что эти атрибуты присутствуют в нескольких файлах overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'