Gunakan library car-ui-lib
untuk meluncurkan sistem infotainmen (IVI) dalam kendaraan
yang konsisten dengan sendirinya. Codelab ini memperkenalkan car-ui-lib
dan cara
menggunakan overlay resource runtime (RRO) untuk menyesuaikan komponen dalam library.
Yang akan Anda pelajari
Caranya:
- Sertakan komponen
car-ui-lib
di aplikasi Android Anda. - Gunakan Gradle untuk mem-build aplikasi Android dan RRO.
- Gunakan RRO dengan
car-ui-lib
.
Codelab ini tidak menjelaskan cara kerja RRO. Lihat Mengubah nilai resource aplikasi saat runtime dan Memecahkan masalah overlay resource runtime untuk mempelajari lebih lanjut.
Sebelum memulai
Prasyarat
Sebelum memulai, pastikan Anda memiliki:
Komputer dengan command line (komputer Linux, Mac, atau Windows dengan Windows Subsystem for Linux).
Perangkat Android atau emulator yang terhubung ke komputer Anda. Lihat Mendownload sumber Android dan Mem-build Android.
Pengetahuan dasar tentang RRO.
Membuat aplikasi Android baru
Durasi: 15 menit
Di bagian ini, Anda akan membuat project Android Studio baru.
Di Android Studio, buat aplikasi dengan
EmptyActivity
.Gambar 1.Membuat Aktivitas Kosong Beri nama aplikasi
CarUiCodelab
, lalu pilih bahasa Java. Anda juga dapat memilih lokasi file jika diinginkan. Setujui nilai default untuk setelan yang tersisa.Gambar 2. Beri nama aplikasi Anda Ganti
activity_main.xml
dengan blok kode berikut:<?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>
Blok kode ini menampilkan string
sample_text
, yang tidak ditentukan.Tambahkan string resource
sample_text
dan tetapkan ke "Hello World!" di filestrings.xml
Anda. Untuk membuka file ini, pilih 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>
Untuk mem-build aplikasi, klik tombol Play hijau di kanan atas. Tindakan ini akan otomatis menginstal apk ke emulator atau perangkat Android Anda melalui Gradle.
Aplikasi baru akan otomatis terbuka di emulator atau perangkat Android Anda. Jika
tidak, buka aplikasi CarUiCodelab
dari peluncur aplikasi, yang kini telah diinstal.
Tampilannya seperti ini:

Menambahkan car-ui-lib ke aplikasi Android
Durasi: 15 menit
Tambahkan car-ui-lib
ke aplikasi Anda:
Untuk menambahkan dependensi
car-ui-lib
ke filebuild.gradle
project Anda, pilih app > build.gradle. Dependensi Anda akan terlihat seperti ini: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' }
Menggunakan komponen car-ui-lib di aplikasi Android
Setelah memiliki car-ui-lib
, tambahkan toolbar ke aplikasi Anda.
Di file
MainActivity.java
, ganti metodeonCreate
:@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); }
Pastikan untuk mengimpor
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
Untuk menggunakan tema
Theme.CarUi.WithToolbar
, pilih app > src > main > AndroidManifest.xml, lalu perbaruiAndroidManifest.xml
agar muncul sebagai berikut:<?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>
Untuk mem-build aplikasi, tekan tombol Play berwarna hijau seperti sebelumnya.
Menambahkan RRO ke aplikasi
Durasi: 30 menit
Jika Anda sudah terbiasa dengan RRO, buka bagian berikut, Menambahkan pengontrol izin ke aplikasi. Jika tidak, untuk mempelajari dasar-dasar RRO, lihat Mengubah nilai resource aplikasi saat runtime.
Menambahkan pengontrol izin ke aplikasi
Untuk mengontrol resource yang ditempatkan paket RRO, tambahkan file bernama
overlayable.xml
ke folder /res
aplikasi Anda. File ini berfungsi sebagai pengontrol
izin antara aplikasi Anda (target) dan paket RRO (overlay).
Tambahkan
res/values/overlayable.xml
ke aplikasi Anda dan salin konten berikut ke file Anda:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
Karena string
sample_text
harus dapat ditempatkan oleh RRO, sertakan nama resource dalam overlayable.xml aplikasi.File
overlayable.xml
Anda HARUS berada dires/values/
. Jika tidak,OverlayManagerService
tidak dapat menemukannya.Untuk mempelajari lebih lanjut resource yang dapat ditempatkan dan cara mengonfigurasinya, lihat Membatasi resource yang dapat ditempatkan.
Membuat paket RRO
Di bagian ini, Anda akan membuat paket RRO untuk mengubah string yang ditampilkan di atas dari "Hello World!" menjadi "Hello World RRO".
Untuk membuat project baru, pilih File > New > New Project. Pastikan untuk memilih Tidak Ada Aktivitas, bukan Aktivitas Kosong karena paket RRO hanya berisi resource.
Konfigurasi Anda akan terlihat mirip dengan yang diilustrasikan di bawah. Lokasi penyimpanan file tersebut mungkin berbeda:
Setelah Anda membuat project
CarUiRRO
baru, deklarasikan project sebagai RRO dengan mengubahAndroidManifest.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>
Tindakan ini akan menyebabkan error pada
@xml/sample_overlay
. FileresourcesMap
memetakan nama resource dari paket target ke paket RRO. Menetapkan tandahasCode
kefalse
wajib dilakukan untuk paket RRO. Selain itu, paket RRO tidak diizinkan untuk berisi file DEX.Salin blok kode berikut ke
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
Tambahkan
sample_text
ke…/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>
Untuk mem-build target RRO, tekan tombol Play hijau untuk membuat build Gradle RRO di emulator atau perangkat Android.
Untuk memverifikasi bahwa RRO Anda diinstal dengan benar, jalankan:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
Perintah ini menampilkan informasi berguna tentang status paket RRO di sistem.
[ ]
menunjukkan bahwa RRO telah diinstal dan siap diaktifkan.---
menunjukkan bahwa RRO diinstal, tetapi berisi error.[X]
berarti RRO diinstal dan diaktifkan.
Jika RRO Anda berisi error, lihat Memecahkan masalah overlay resource runtime sebelum melanjutkan.
Untuk mengaktifkan RRO dan memverifikasi bahwa RRO telah diaktifkan:
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
Aplikasi Anda menampilkan string "Hello World RRO".

Selamat! Anda telah membuat RRO pertama.
Saat menggunakan RRO, sebaiknya gunakan tanda Android Asset Packaging Tool (AAPT2)
--no-resource-deduping
dan --no-resource-removal
yang dijelaskan dalam
Opsi link.
Anda tidak perlu menambahkan flag dalam codelab ini, tetapi sebaiknya gunakan flag tersebut
di RRO untuk menghindari penghapusan resource (dan masalah proses debug). Anda
dapat menambahkannya ke file build.gradle
RRO seperti ini:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Untuk mempelajari flag ini lebih lanjut, lihat Mem-build paket dan AAPT2.
Mengubah komponen car-ui-lib
menggunakan RRO di aplikasi Android Anda
Halaman ini menjelaskan cara menggunakan overlay resource runtime (RRO) untuk
mengubah komponen dari library car-ui-lib
di aplikasi Android Anda.
Menetapkan warna latar belakang toolbar
Durasi: 15 menit
Untuk mengubah warna latar belakang toolbar:
Tambahkan nilai berikut ke aplikasi RRO Anda, dan tetapkan resource ke hijau terang (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
Library
car-ui-lib
berisi resource bernamacar_ui_toolbar_background
. Jika resource ini terdapat dalam konfigurasi RRO, toolbar tidak akan berubah karena nilai yang salah ditargetkan.Di
AndroidManifest.xml
untuk RRO Anda, perbaruitargetName
agar mengarah kecar-ui-lib
:… android:targetName="car-ui-lib" …
Anda HARUS membuat paket RRO baru untuk setiap paket target yang ingin Anda RRO. Misalnya, saat membuat overlay untuk dua target yang berbeda, Anda harus membuat dua apk overlay.
Build, verifikasi, instal, dan aktifkan RRO dengan cara yang sama seperti sebelumnya.
Aplikasi Anda akan terlihat seperti ini:

Tata letak dan gaya RRO
Durasi: 15 menit
Dalam latihan ini, Anda akan mem-build aplikasi baru yang mirip dengan aplikasi yang Anda build sebelumnya. Aplikasi ini memungkinkan tata letak ditempatkan. Ikuti langkah-langkah yang sama seperti sebelumnya, atau ubah aplikasi yang ada.
Pastikan Anda menambahkan baris berikut ke
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>
Pastikan
activity_main.xml
muncul sebagai berikut:<?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>
Di aplikasi RRO, buat
res/layout/activity_main.xml
dan tambahkan hal berikut:<?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>
Update
res/values/styles.xml
untuk menambahkan gaya kita ke 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>
Ubah
targetName
diAndroidManifest.xml
agar mengarah ke nama aplikasi baru Anda:… android:targetName="CarUiCodelab" …
Tambahkan resource ke file
sample_overlay.xml
di RRO Anda:<?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>
Build dan instal aplikasi serta RRO dengan cara yang sama seperti sebelumnya (tombol Play berwarna hijau). Pastikan untuk mengaktifkan RRO Anda.
Aplikasi dan RRO dirender sebagai berikut. Teks RRO Hello World berwarna hijau dan dipusatkan seperti yang ditentukan dalam RRO tata letak.

Menambahkan CarUiRecyclerView ke aplikasi
Durasi: 15 menit
Antarmuka CarUiRecyclerView
menyediakan API untuk mengakses RecyclerView
yang disesuaikan melalui resource car-ui-lib
. Misalnya, CarUiRecyclerView
memeriksa tanda saat runtime untuk menentukan apakah scrollbar harus diaktifkan atau tidak
dan memilih tata letak yang sesuai.

Untuk menambahkan
CarUiRecyclerView
, tambahkan ke fileactivity_main.xml
danMainActivity.java
. Anda dapat membuat aplikasi baru dari awal atau mengubah aplikasi yang ada. Jika Anda mengubah aplikasi yang ada, pastikan untuk menghapus resource yang tidak dideklarasikan darioverlayable.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"/>
Error berikut mungkin muncul, yang dapat Anda abaikan:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
Selama class Anda dieja dengan benar dan Anda telah menambahkan
car-ui-lib
sebagai dependensi, Anda dapat mem-build dan mengompilasi apk. Untuk menghapus error, pilih File > Invalidate Caches, lalu klik Invalidate and Restart.Tambahkan kode berikut ke
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; }
Build dan instal aplikasi Anda seperti sebelumnya.
Sekarang Anda melihat CarUiRecyclerView
:

Menggunakan RRO untuk menghapus scrollbar
Durasi: 10 menit
Latihan ini menunjukkan cara menggunakan RRO untuk menghapus scrollbar dari
CarUiRecyclerView
.
Di RRO, tambahkan dan ubah file berikut:
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>
Resource
car_ui_scrollbar_enable
adalah resource booleancar-ui-lib
, yang mengontrol apakah scrollbar yang dioptimalkan mobil dengan tombol Atas dan Bawah diCarUiRecyclerView
ada atau tidak. Jika ditetapkan kefalse
,CarUiRecyclerView
akan berfungsi sepertiRecyclerView
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>
Build dan instal aplikasi Anda seperti sebelumnya. Scrollbar kini dihapus dari
CarUiRecyclerView
:

Menggunakan tata letak untuk menempatkan scrollbar CarUiRecyclerView
Durasi: 15 menit
Dalam latihan ini, Anda akan mengubah tata letak scrollbar CarUiRecyclerView
.
Tambahkan dan ubah file berikut di aplikasi RRO Anda.
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>
Untuk menempatkan file tata letak, Anda harus menambahkan semua ID dan atribut namespace ke
overlay.xml
RRO Anda. Lihat file di bawah.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>
Sebaiknya periksa cara file ini berinteraksi.
Untuk memudahkan, dimensi dan warna di-hardcode. Namun, praktik terbaik adalah mendeklarasikan nilai ini di
dimens.xml
dancolors.xml
atau bahkan ditetapkan sebagai file warna di folderres/color/
. Untuk mempelajari lebih lanjut, lihat Gaya kode Java AOSP untuk kontributor.Build dan instal aplikasi Anda seperti sebelumnya. Anda telah mem-build
CarUiRecyclerView
dengan scrollbar biru dan kolom samping abu-abu.
Selamat! Kedua panah muncul di sepanjang bagian bawah scrollbar. Anda telah
berhasil menerapkan RRO ke file resource tata letak car-ui-lib
menggunakan sistem build
Gradle melalui Android Studio.

Item Daftar RRO
Durasi: 15 menit
Sampai tahap ini, Anda telah menerapkan RRO ke komponen car-ui-lib
menggunakan komponen
framework (bukan AndroidX). Untuk menggunakan komponen AndroidX di RRO, Anda harus menambahkan
dependensi komponen tersebut ke aplikasi dan ke build.gradle.
RRO. Anda
juga harus menambahkan attrs
komponen tersebut ke overlayable.xml
di aplikasi, serta
sample_overlay.xml
di RRO.
Library kita (car-ui-lib
) menggunakan ConstraintLayout
serta komponen AndroidX
lainnya, sehingga overlayable.xml
-nya mungkin terlihat seperti ini:
<?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>
Ubah tata letak item daftar di
CarUiRecyclerView
menggunakanConstraintLayout
. Tambahkan atau ubah file berikut di RRO Anda: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
mereferensikan beberapa referensi beberapa komponen/ resource yang tidak disertakan sebagai dependensi aplikasi. Ini adalah resourcecar-ui-lib
. Anda dapat memperbaikinya dengan menambahkancar-ui-lib
sebagai dependensi ke aplikasi RRO diapp/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' }
Judul dan Isi kini rata kanan, bukan rata kiri.

Kami hanya menerapkan RRO ke car-ui-lib
menggunakan komponen AndroidX
(ConstraintLayout
) jika atributnya ada dalam file car-ui-lib
bernama overlayable.xml
serta RRO sample_overlay.xml
. Anda
dapat melakukan hal serupa di aplikasi Anda sendiri. Cukup tambahkan semua
attrs
yang sesuai ke overlayable.xml
aplikasi Anda, mirip dengan car-ui-lib
.
Namun, tidak dapat melakukan RRO pada aplikasi yang menggunakan komponen AndroidX saat
aplikasi memiliki car-ui-lib
sebagai dependensi dalam build.gradle
-nya (saat aplikasi menggunakan
komponen car-ui-lib
). Karena pemetaan atribut sudah ditentukan di
overlayable.xml
library car-ui-lib
, menambahkannya ke
overlayable.xml
aplikasi Anda dengan car-ui-lib
sebagai dependensi akan menyebabkan
error mergeDebugResources
seperti di bawah. Hal ini karena atribut ini
ada dalam beberapa file overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'