از کتابخانه car-ui-lib برای راهاندازی سیستمهای سرگرمی-اطلاعاتی درونخودرویی (IVI) خودسازگار استفاده کنید. این آزمایشگاه کد شما را با car-ui-lib و نحوه استفاده از پوششهای منابع زمان اجرا (RRO) برای سفارشیسازی اجزای موجود در کتابخانه آشنا میکند.
آنچه یاد خواهید گرفت
چگونه:
- کامپوننتهای
car-ui-libرا در برنامه اندروید خود قرار دهید. - از Gradle برای ساخت برنامههای اندروید و RRO استفاده کنید.
- از RROها به همراه
car-ui-libاستفاده کنید.
این آزمایشگاه کد، جزئیات نحوهی کار RROها را شرح نمیدهد. برای کسب اطلاعات بیشتر، به «تغییر مقدار منابع یک برنامه در زمان اجرا» و «عیبیابی همپوشانیهای منابع زمان اجرا» مراجعه کنید.
قبل از شروع
پیشنیازها
قبل از شروع، مطمئن شوید که موارد زیر را دارید:
رایانهای با خط فرمان (دستگاه لینوکس، مک یا دستگاه ویندوز با زیرسیستم ویندوز برای لینوکس).
دستگاه یا شبیهساز اندروید را به دستگاه خود متصل کنید. به بخش دانلود منبع اندروید و ساخت اندروید مراجعه کنید.
دانش اولیه در مورد RRO ها.
یک برنامه اندروید جدید ایجاد کنید
مدت زمان: ۱۵ دقیقه
در این بخش، شما یک پروژه جدید اندروید استودیو ایجاد میکنید.
در اندروید استودیو یک برنامه با
EmptyActivityایجاد کنید.
شکل ۱. ایجاد یک اکتیویتی خالی نام برنامه را
CarUiCodelabبگذارید و سپس زبان جاوا را انتخاب کنید. در صورت تمایل میتوانید محل ذخیره فایل را نیز انتخاب کنید. مقادیر پیشفرض را برای سایر تنظیمات بپذیرید.
شکل ۲. نام برنامه خود را بنویسید 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را اضافه کنید و آن را در فایلstrings.xmlخود روی "Hello World!" تنظیم کنید. برای باز کردن این فایل، 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>برای ساخت برنامه، روی دکمه سبز Play در بالا سمت راست کلیک کنید. با انجام این کار، فایل apk به طور خودکار از طریق Gradle روی شبیهساز یا دستگاه اندروید شما نصب میشود.

برنامه جدید باید به طور خودکار روی شبیهساز یا دستگاه اندروید شما باز شود. در غیر این صورت، برنامه CarUiCodelab را از لانچر برنامه که اکنون نصب شده است، باز کنید. چیزی شبیه به این خواهد بود:

افزودن car-ui-lib به برنامه اندروید شما
مدت زمان: ۱۵ دقیقه
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 در برنامه اندروید خود استفاده کنید
حالا که 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، app > 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>برای ساخت برنامه، مانند قبل دکمه سبز Play را فشار دهید.

RRO ها را به برنامه خود اضافه کنید
مدت زمان: ۳۰ دقیقه
اگر با RROها آشنا هستید، به بخش بعدی، یعنی «افزودن یک کنترلکننده مجوز به برنامه» مراجعه کنید. در غیر این صورت، برای یادگیری اصول اولیه RROها، به بخش «تغییر مقدار منابع یک برنامه در زمان اجرا» مراجعه کنید.
یک کنترلکننده مجوز به برنامه خود اضافه کنید
برای کنترل اینکه یک بسته RRO کدام منابع را همپوشانی میکند، فایلی با نام overlayable.xml را به پوشه /res برنامه خود اضافه کنید. این فایل به عنوان یک کنترلکننده مجوز بین برنامه شما ( target ) و بسته RRO شما ( overlay ) عمل میکند.
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" تغییر دهد.
برای ایجاد یک پروژه جدید، File > New > New Project را انتخاب کنید. حتماً به جای Empty Activity، گزینه No Activity را انتخاب کنید، زیرا بستههای RRO فقط شامل منابع هستند.

پیکربندیهای شما مشابه موارد نشان داده شده در زیر هستند. محل ذخیره آنها ممکن است متفاوت باشد:

پس از ایجاد پروژه جدید
CarUiRRO، با تغییرAndroidManifest.xml، پروژه را به عنوان یک RRO اعلام کنید.<?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 نگاشت میکند. تنظیم flaghasCodeرویfalseبرای بستههای RRO الزامی است. علاوه بر این، بستههای RRO مجاز به داشتن فایلهای DEX نیستند.کد زیر را در
…/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 خود، دکمه سبز Play را فشار دهید تا یک نسخه Gradle از RRO خود را روی شبیهساز یا دستگاه اندروید خود ایجاد کنید.
برای تأیید نصب صحیح 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" را نمایش میدهد.

تبریک میگویم! شما اولین RRO خود را ایجاد کردید.
هنگام استفاده از RROها، ممکن است بخواهید از فلگهای --no-resource-deduping و --no-resource-removal ابزار بستهبندی داراییهای اندروید (AAPT2) که در گزینههای Link توضیح داده شدهاند، استفاده کنید. اضافه کردن فلگها در این آزمایشگاه کد ضروری نیست، اما پیشنهاد میکنیم برای جلوگیری از حذف منابع (و دردسرهای اشکالزدایی) از آنها در RROهای خود استفاده کنید. میتوانید آنها را به فایل build.gradle RRO خود به این صورت اضافه کنید:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
برای کسب اطلاعات بیشتر در مورد این پرچمها، به ساخت بسته و AAPT2 مراجعه کنید.
اصلاح کامپوننتهای car-ui-lib با استفاده از RROها در برنامه اندروید شما
این صفحه نحوه استفاده از یک پوشش منابع زمان اجرا (RRO) را برای تغییر اجزای کتابخانه car-ui-lib در برنامه اندروید شما شرح میدهد.
تنظیم رنگ پس زمینه نوار ابزار
مدت زمان: ۱۵ دقیقه
برای تغییر رنگ پس زمینه نوار ابزار:
مقدار زیر را به برنامه 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 را به همان روش قبلی بسازید، تأیید کنید، نصب کنید و فعال کنید.
برنامه شما به این شکل نمایش داده میشود:

طرحبندیها و سبکهای RRO
مدت زمان: ۱۵ دقیقه
در این تمرین، شما یک برنامه جدید مشابه برنامهای که قبلاً ساختهاید، میسازید. این برنامه امکان همپوشانی طرحبندی را فراهم میکند. همان مراحل قبلی را دنبال کنید یا برنامه موجود خود را تغییر دهید.
مطمئن شوید که خطوط زیر را به
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 را مانند قبل (با دکمه سبز Play ) بسازید و نصب کنید. حتماً RRO خود را فعال کنید.
برنامه و RRO به صورت زیر رندر میشوند. متن Hello World RRO سبز رنگ است و طبق طرحبندی RRO در مرکز قرار گرفته است.

CarUiRecyclerView را به برنامه خود اضافه کنید
مدت زمان: ۱۵ دقیقه
رابط کاربری CarUiRecyclerView رابطهای برنامهنویسی کاربردی (API) را برای دسترسی به یک RecyclerView که از طریق منابع car-ui-lib سفارشیسازی شده است، فراهم میکند. برای مثال، CarUiRecyclerView در زمان اجرا یک پرچم (flag) را بررسی میکند تا مشخص کند که آیا نوار اسکرول باید فعال باشد یا خیر و طرحبندی مربوطه را انتخاب میکند.

برای افزودن
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 خود را بسازید و کامپایل کنید. برای رفع خطا، File > Invalidate Caches را انتخاب کنید و سپس روی Invalidate and Restart کلیک کنید.موارد زیر را به
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 میبینید:

از RRO برای حذف نوار پیمایش استفاده کنید
مدت زمان: ۱۰ دقیقه
این تمرین به شما نشان میدهد که چگونه از یک 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 استفاده کنید
مدت زمان: ۱۵ دقیقه
در این تمرین، طرحبندی نوار اسکرول 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/تعیین کنید. برای کسب اطلاعات بیشتر، به بخش سبک کد جاوا AOSP برای مشارکتکنندگان مراجعه کنید.برنامه خود را مانند قبل بسازید و نصب کنید. شما
CarUiRecyclerViewبا یک اسکرول بار آبی و ریلهای خاکستری ساختهاید.
تبریک! هر دو فلش در پایین نوار پیمایش ظاهر میشوند. شما با موفقیت یک RRO را با استفاده از سیستم ساخت Gradle از طریق اندروید استودیو به فایل منبع طرحبندی car-ui-lib اعمال کردهاید.

اقلام فهرست RRO
مدت زمان: ۱۵ دقیقه
تا این مرحله، شما یک RRO را با استفاده از کامپوننتهای فریمورک (نه AndroidX) به کامپوننتهای car-ui-lib اعمال کردهاید. برای استفاده از کامپوننتهای AndroidX در یک 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' }
عنوان و بدنه اکنون به جای تراز چپ، راستچین شدهاند.

ما فقط زمانی یک RRO را با استفاده از کامپوننتهای AndroidX ( ConstraintLayout ) به car-ui-lib اعمال کردیم که ویژگیهای آن در فایل car-ui-lib به نام overlayable.xml و همچنین RRO sample_overlay.xml وجود داشته باشند. انجام کاری مشابه در برنامه خودتان نیز امکانپذیر است. فقط تمام attrs مربوطه را به overlayable.xml برنامه خود اضافه کنید، مشابه car-ui-lib .
با این حال، وقتی برنامه car-ui-lib را به عنوان یک وابستگی در build.gradle خود دارد (وقتی برنامه از اجزای car-ui-lib استفاده میکند)، RRO کردن یک برنامه با استفاده از اجزای AndroidX امکانپذیر نیست . از آنجایی که نگاشتهای ویژگی قبلاً در overlayable.xml کتابخانه car-ui-lib تعریف شدهاند، اضافه کردن آنها به overlayable.xml برنامه شما با car-ui-lib به عنوان یک وابستگی، باعث خطای mergeDebugResources مانند زیر میشود. دلیل این امر این است که این ویژگیها در چندین فایل overlayable.xml وجود دارند:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'