از کتابخانه car-ui-lib برای راهاندازی سیستمهای سرگرمی (IVI) خودسازگار، درون خودرویی استفاده کنید. این Codelab شما را با car-ui-lib و نحوه استفاده از همپوشانی منابع زمان اجرا (RRO) برای سفارشی کردن اجزای کتابخانه آشنا می کند.
چیزی که یاد خواهید گرفت
چگونه:
- اجزای
car-ui-libرا در برنامه اندروید خود قرار دهید. - از Gradle برای ساخت برنامه های اندروید و RRO استفاده کنید.
- از RRO با
car-ui-libاستفاده کنید.
این کد لبه جزئیات نحوه عملکرد RRO ها را توضیح نمی دهد. برای اطلاعات بیشتر به تغییر مقدار منابع برنامه در زمان اجرا و عیب یابی همپوشانی منابع زمان اجرا مراجعه کنید.
قبل از شروع
پیش نیازها
قبل از شروع، مطمئن شوید که:
رایانه با خط فرمان (ماشین لینوکس، مک یا دستگاه ویندوز با زیرسیستم ویندوز برای لینوکس).
دستگاه اندروید یا شبیه ساز متصل به دستگاه شما. به دانلود سورس اندروید و ساخت اندروید مراجعه کنید.
دانش اولیه RROs
یک برنامه اندروید جدید ایجاد کنید
مدت زمان: 15 دقیقه
در این بخش شما یک پروژه اندروید استودیو جدید ایجاد می کنید.
در Android Studio یک برنامه با
EmptyActivityایجاد کنید.
شکل 1. یک فعالیت خالی ایجاد کنید نام برنامه را
CarUiCodelabبگذارید و سپس زبان جاوا را انتخاب کنید. در صورت تمایل می توانید محل فایل را نیز انتخاب کنید. مقادیر پیش فرض را برای تنظیمات باقیمانده بپذیرید.
شکل 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>برای ساخت اپلیکیشن خود، روی دکمه سبز رنگ Play در بالا سمت راست کلیک کنید. با انجام این کار، apk به طور خودکار از طریق Gradle در شبیه ساز یا دستگاه اندرویدی شما نصب می شود.

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

car-ui-lib را به برنامه اندروید خود اضافه کنید
مدت زمان: 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 در برنامه اندروید خود استفاده کنید
اکنون که 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 ها را به برنامه خود اضافه کنید
مدت زمان: 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".
برای ایجاد یک پروژه جدید، File > New > New Project را انتخاب کنید. مطمئن شوید که No Activity را به جای Empty 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، ممکن است بخواهید از پرچمهای ابزار بستهبندی دارایی Android (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 در برنامه اندروید خود تغییر دهید
این صفحه نحوه استفاده از همپوشانی منبع زمان اجرا (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 را به همان روش قبلی بسازید، تأیید کنید، نصب کنید و فعال کنید.
برنامه شما به این شکل ظاهر می شود:

طرحبندیها و سبکهای 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>برای اضافه کردن سبک خود به RRO
res/values/styles.xmlرا بهروزرسانی کنید:<?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 به صورت زیر ارائه می شوند. متن Hello World RRO سبز است و همانطور که در طرح بندی RRO مشخص شده است در مرکز قرار دارد.

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

برای افزودن
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 و 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 برای حذف نوار اسکرول استفاده کنید
مدت زمان: 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 استفاده کنید
مدت زمان: 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.xmlRRO خود اضافه کنید. فایل های زیر را ببینید.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 را به فایل منبع طرحبندی car-ui-lib با استفاده از سیستم ساخت Gradle از طریق Android Studio اعمال کردهاید.

موارد فهرست RRO
مدت زمان: 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' }
اکنون عنوان و متن به جای تراز چپ، راست چین شده اند.

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