استخدِم مكتبة "car-ui-lib
" لتوفير تجربة المعلومات والترفيه داخل المركبة.
(IVI). يقدّم لك هذا الدرس التطبيقي حول الترميز التعرّف على car-ui-lib
وكيفية استخدام
استخدام تراكبات موارد وقت التشغيل (RROs) لتخصيص المكونات في المكتبة.
المعلومات التي ستطّلع عليها
كيفية:
- ضمِّن
car-ui-lib
عنصرًا في تطبيق Android. - استخدِم Gradle لإنشاء تطبيقات Android وRRO.
- استخدِم قوائم الموارد المجمَّعة مع "
car-ui-lib
".
لا يوضِّح هذا الدرس التطبيقي حول الترميز بالتفصيل طريقة عمل قوائم الموارد المنتظمة (RRO). عرض تغيير قيمة موارد التطبيق في وقت التشغيل تحديد مشاكل تراكبات موارد وقت التشغيل وحلّها لمعرفة المزيد.
قبل البدء
المتطلّبات الأساسية
قبل البدء، تأكَّد من توفُّر ما يلي:
كمبيوتر يحتوي على سطر أوامر (جهاز Linux أو Mac أو Windows يحتوي على Windows الفرعي لنظام التشغيل Linux).
تم ربط جهاز Android أو المحاكي بجهازك. عرض نزِّل مصدر Android و إنشاء Android:
معرفة أساسية بـ RRO.
إنشاء تطبيق Android جديد
المدة: 15 دقيقة
في هذا القسم، يمكنك إنشاء مشروع جديد على "استوديو Android".
في "استوديو Android"، أنشِئ تطبيقًا باستخدام
EmptyActivity
.الشكل 1.إنشاء نشاط فارغ أدخِل اسمًا للتطبيق
CarUiCodelab
ثم اختَر لغة Java. يمكنك أيضًا تحديد موقع الملف إذا رغبت في ذلك. اقبل القيم الافتراضية الإعدادات المتبقية.الشكل 2. أدخِل اسمًا للتطبيق استبدِل
activity_main.xml
بمجموعة الرموز التالية:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
تعرض مجموعة الرموز هذه السلسلة
sample_text
التي لم يتم تعريفها.أضِف سلسلة موارد
sample_text
واضبطها على "Hello World!" في ملفstrings.xml
. لفتح هذا الملف، اختَر تطبيق > src > الصفحة الرئيسية > الدقة > القيم > schema.xml.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
لإنشاء تطبيقك، انقر على الزر تشغيل الأخضر أعلى اليسار. إجراء ذلك تثبّت ملف APK تلقائيًا على المحاكي أو على جهاز Android من خلال Gradle.
من المفترض أن يتم فتح التطبيق الجديد تلقائيًا على المحاكي أو جهاز Android. في حال حذف
لا، افتح تطبيق CarUiCodelab
من مشغِّل التطبيقات المثبّت الآن.
يظهر على النحو التالي:
![فتح تطبيق CarUiCodelab الجديد](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=ar)
إضافة Car-ui-lib إلى تطبيق Android
المدة: 15 دقيقة
أضِف "car-ui-lib
" إلى تطبيقك:
لإضافة الاعتمادية
car-ui-lib
إلى ملفbuild.gradle
الخاص بمشروعك، اتّبِع الخطوات التالية: اختَر التطبيق > Build.gradle. يُفترض أن تظهر تبعياتك على النحو التالي:dependencies { implementation 'com.android.car.ui:car-ui-lib:2.0.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' }
استخدام مكونات Car-ui-lib في تطبيق Android
الآن بعد أن أصبح لديك car-ui-lib
، أضف شريط أدوات إلى تطبيقك.
في ملف
MainActivity.java
، استبدِل طريقةonCreate
:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the toolbar controller instance. ToolbarController toolbar = CarUi.getToolbar(this); // Set the title on toolbar. toolbar.setTitle(getTitle()); // Set the logo to be shown with the title. toolbar.setLogo(R.mipmap.ic_launcher_round); }
تأكد من استيراد
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
لاستخدام المظهر
Theme.CarUi.WithToolbar
، اختَر التطبيق > src > الرئيسية > AndroidManifest.xml، ثم تحديثAndroidManifest.xml
لتظهر على النحو التالي:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.caruicodelab"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.CarUi.WithToolbar" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
لإنشاء التطبيق، اضغط على الزر تشغيل كما في السابق.
إضافة حسابات RRO إلى تطبيقك
المدة: 30 دقيقة
إذا كنت على دراية بـ RROs، انتقِل إلى ، أضِف وحدة تحكُّم بالأذونات إلى تطبيقك. بخلاف ذلك، لمعرفة أساسيات RROs، راجع تغيير قيمة موارد التطبيق في وقت التشغيل
إضافة وحدة تحكّم بالأذونات إلى تطبيقك
للتحكم في الموارد التي تراكبها حزمة RRO، أضف ملفًا باسم
overlayable.xml
إلى مجلد التطبيق /res
. يتم استخدام هذا الملف كإذن.
وحدة التحكّم بين تطبيقك (target) وحزمة RRO (التراكب).
أضِف "
res/values/overlayable.xml
" إلى تطبيقك وانسخ المحتوى التالي في ملفك وهي:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
نظرًا لأنه يجب أن تكون السلسلة
sample_text
قابلة للتراكب بواسطة RRO، يجب تضمين اسم المورد في ملفOverlayable.xml للتطبيق.يجب وضع ملف
overlayable.xml
فيres/values/
. وإذا لم يكن كذلك، سيتم يتعذّر على "OverlayManagerService
" تحديد موقعه.لمعرفة المزيد من المعلومات حول الموارد القابلة للتراكب وكيفية استخدامها مهيأ، راجع تقييد قابلية التراكب الموارد
إنشاء حزمة RRO
في هذا القسم، يمكنك إنشاء حزمة RRO لتغيير السلسلة المعروضة أعلاه من "Hello World!" إلى "Hello World RRO".
لإنشاء مشروع جديد، اختَر ملف > جديد > مشروع جديد: تأكد من حدِّد بلا نشاط بدلاً من إفراغ النشاط حيث تحتوي حِزم RRO على الموارد فقط.
تظهر الإعدادات بشكل مشابه لتلك الموضّحة أدناه. تشير رسالة الأشكال البيانية وقد يختلف الموقع الجغرافي الذي يتم حفظها فيه:
بعد إنشاء مشروع
CarUiRRO
الجديد، عليك الإفصاح عن المشروع على أنّه RRO عن طريق تعديلAndroidManifest.xml
.<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.caruirro"> <application android:hasCode="false" /> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> <overlay android:targetPackage="com.example.caruicodelab" android:targetName="CarUiCodelab" android:isStatic="false" android:resourcesMap="@xml/sample_overlay" /> </manifest>
يؤدي ذلك إلى حدوث خطأ في "
@xml/sample_overlay
".resourcesMap
يعين الملف أسماء الموارد من الحزمة المستهدفة إلى حزمة RRO.انسخ مجموعة الرموز التالية إلى
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
إضافة
sample_text
إلى…/res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
لإنشاء هدف RRO، اضغط على الزر الأخضر تشغيل لإنشاء قاعدة Gradle من RRO على المحاكي أو على جهاز Android.
للتحقّق من تثبيت RRO الخاص بك بشكل صحيح، قم بتشغيل:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
يعرض هذا الأمر معلومات مفيدة عن حالة حزم RRO على النظام.
- يشير
[ ]
إلى أنّ RRO مثبّت وجاهزة للتفعيل. ---
يشير إلى أنه تم تثبيت RRO ولكنه يحتوي على أخطاء.- تعني القيمة
[X]
أنّه تم تثبيت RRO وتفعيله.
إذا احتوت RRO على أخطاء، راجِع تحديد مشاكل تراكبات موارد وقت التشغيل وحلّها قبل المتابعة.
- يشير
لتمكين RRO والتحقق من تمكينه:
shell:~$ adb shell cmd overlay enable --user current com.example.caruirro shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [x] com.example.caruirro
يعرض تطبيقك السلسلة "Hello World RRO".
![مرحبًا بالعالم RRO!](https://source.android.com/static/docs/automotive/images/codelab_09.png?hl=ar)
تهانينا! لقد أنشأت أول RRO لك.
عند استخدام RROs، ننصحك باستخدام أداة Android Asset Packaging Tool (AAPT2).
تم وصف العلامتين --no-resource-deduping
و--no-resource-removal
في
خيارات الربط
ليس من الضروري إضافة العلامات في هذا الدرس التطبيقي حول الترميز، ولكننا نقترح عليك استخدامها.
في قوائم الموارد المنتظمة (RRO) لتجنب إزالة الموارد (وتصحيح المشكلات). إِنْتَ
يمكنك إضافتها إلى ملف build.gradle
في RRO على النحو التالي:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
لمزيد من المعلومات عن هذه العلامات، راجع إنشاء الحزمة AAPT2
تعديل مكوّنَين (car-ui-lib
) باستخدام قوائم RRO في تطبيق Android
توضّح هذه الصفحة كيفية استخدام ميزة "تراكب موارد وقت التشغيل" (RRO) بهدف
تعديل المكونات من مكتبة car-ui-lib
في تطبيق Android.
ضبط لون خلفية شريط الأدوات
المدة: 15 دقيقة
لتغيير لون خلفية شريط الأدوات:
إضافة القيمة التالية إلى تطبيق RRO وضبط المورد على درجة سطوع أخضر (
#0F0
):<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>
تحتوي مكتبة
car-ui-lib
على مورد باسمcar_ui_toolbar_background
عندما يتم تضمين هذا المورد في RRO، لا يتغير شريط الأدوات لأن القيمة الخاطئة استهداف العملاء.في
AndroidManifest.xml
لـ RRO، يجب تعديلtargetName
للإشارة إلىcar-ui-lib
:… android:targetName="car-ui-lib" …
يجب عليك إنشاء حزمة RRO جديدة لكل حزمة مستهدفة تريد RRO. على سبيل المثال، عند إنشاء تراكبات لاستهدافين مختلفين، يجب إنشاء اثنين من حزم APK المتراكبة.
يمكنك إنشاء RRO وإثبات صحتها وتثبيتها وتفعيلها بالطريقة نفسها المُتّبعة في السابق.
يظهر تطبيقك على النحو التالي:
![لون خلفية شريط الأدوات الجديد](https://source.android.com/static/docs/automotive/images/codelab_10.png?hl=ar)
تخطيطات وأنماط RRO
المدة: 15 دقيقة
في هذا التمرين، تقوم بإنشاء تطبيق جديد مشابه للتطبيق الذي أنشأته سابقًا. هذا النمط تطبيق يتيح تركيب التخطيط. اتبع الخطوات نفسها كما كانت من قبل أو عدّل لتطبيقك الحالي.
تأكد من إضافة الأسطر التالية إلى
overlayable.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> <item type="layout" name="activity_main"/> <item type="id" name="textView"/> </policy> </overlayable> </resources>
تأكَّد من ظهور
activity_main.xml
على النحو التالي:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
في تطبيق RRO، أنشِئ
res/layout/activity_main.xml
وأضِف التالي:<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" android:textAppearance="@style/TextAppearance.CarUi" android:layout_gravity="center_vertical|center_horizontal"/> </FrameLayout>
يجب تعديل "
res/values/styles.xml
" لإضافة نمطنا إلى RRO:<?xml version="1.0" encoding="utf-8"?> <resources> <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault"> <item name="android:textColor">#0f0</item> <item name="android:textSize">100sp</item> </style> </resources>
تغيير
targetName
فيAndroidManifest.xml
للإشارة إلى اسم تطبيقك الجديد:… android:targetName="CarUiCodelab" …
أضِف الموارد إلى ملف
sample_overlay.xml
في RRO:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> <item target="id/textView" value="@id/textView"/> <item target="layout/activity_main" value="@layout/activity_main"/> </overlay>
إنشاء وتثبيت التطبيق وRRO بالطريقة نفسها (أخضر Play) ). تأكد من تمكين RRO.
يتم عرض التطبيق وRRO على النحو التالي. يظهر نص Hello World RRO باللون الأخضر كما هو محدد في تخطيط RRO.
![مرحبًا بالعالم RRO](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=ar)
إضافة CarUiRecyclerView إلى تطبيقك
المدة: 15 دقيقة
توفّر واجهة CarUiRecyclerView
واجهات برمجة تطبيقات للوصول إلى RecyclerView
التي يتم تخصيصها من خلال car-ui-lib
مورد. على سبيل المثال: CarUiRecyclerView
تتحقّق من علامة في وقت التشغيل لتحديد ما إذا كان يجب تفعيل شريط التمرير
وتحدد التخطيط المتجاوب.
![CarUiRecyclerViewContainer](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=ar)
لإضافة "
CarUiRecyclerView
"، يجب إضافته إلىactivity_main.xml
MainActivity.java
ملف. يمكنك إما إنشاء تطبيق جديد من البداية أو تعديل التطبيق الحالي. في حال تعديل التطبيق الحالي، احرص على إزالته مصادر غير معرَّفة منoverlayable.xml
.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <com.android.car.ui.recyclerview.CarUiRecyclerView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
قد يظهر الخطأ التالي، ويمكنك تجاهله:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
طالما أنّ الصف مكتوب بشكل صحيح، وأنّك أضفت
car-ui-lib
بصفة يمكنك إنشاء وتجميع ملف apk. لإزالة الخطأ، حدد ملف > إلغاء صلاحية ذاكرات التخزين المؤقت ثم انقر على إلغاء الصلاحية وإعادة التشغيل.إضافة ما يلي إلى
MainActivity.java
package com.example.caruicodelab; import android.app.Activity; import android.os.Bundle; import com.android.car.ui.core.CarUi; import com.android.car.ui.recyclerview.CarUiContentListItem; import com.android.car.ui.recyclerview.CarUiListItem; import com.android.car.ui.recyclerview.CarUiListItemAdapter; import com.android.car.ui.recyclerview.CarUiRecyclerView; import com.android.car.ui.toolbar.ToolbarController; import java.util.ArrayList; /** Activity with a simple car-ui layout. */ public class MainActivity extends Activity { private final ArrayList<CarUiListItem> mData = new ArrayList<>(); private CarUiListItemAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ToolbarController toolbar = CarUi.getToolbar(this); toolbar.setTitle(getTitle()); toolbar.setLogo(R.mipmap.ic_launcher_round); CarUiRecyclerView recyclerView = findViewById(R.id.list); mAdapter = new CarUiListItemAdapter(generateSampleData()); recyclerView.setAdapter(mAdapter); } private ArrayList<CarUiListItem> generateSampleData() { for (int i = 0; i < 20; i++) { CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.ICON); item.setTitle("Title " + i); item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT); item.setIcon(getDrawable(R.drawable.ic_launcher_foreground)); item.setBody("body " + i); mData.add(item); } return mData; }
أنشئ تطبيقك وثبِّته على النحو السابق.
يظهر لك الآن CarUiRecyclerView
:
![عرض CarUiRecyclerView](https://source.android.com/static/docs/automotive/images/codelab_13.png?hl=ar)
استخدام 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
" مثلRecyclerView
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>
أنشئ تطبيقك وثبِّته على النحو السابق. تمت الآن إزالة شريط التمرير من
CarUiRecyclerView
:
![CarUiRecyclerView بدون شريط تمرير](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=ar)
استخدام تنسيق لتراكب شريط التمرير CarUiRecyclerView
المدة: 15 دقيقة
في هذا التمرين، يمكنك تعديل تنسيق شريط التمرير CarUiRecyclerView
.
أضف الملفات التالية وعدِّلها في تطبيق RRO.
res/layout/car_ui_recycler_view_scrollbar.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="112dp" android:layout_height="match_parent" android:id="@+id/car_ui_scroll_bar"> <!-- View height is dynamically calculated during layout. --> <View android:id="@+id/car_ui_scrollbar_thumb" android:layout_width="6dp" android:layout_height="20dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:background="@drawable/car_ui_recyclerview_scrollbar_thumb"/> <View android:id="@+id/car_ui_scrollbar_track" android:layout_width="10dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:layout_centerHorizontal="true" android:layout_above="@+id/car_ui_scrollbar_page_up"/> <View android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:background="#323232" android:layout_toLeftOf="@+id/car_ui_scrollbar_thumb" android:layout_above="@+id/car_ui_scrollbar_page_up" android:layout_marginRight="5dp"/> <View android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginTop="10dp" android:background="#323232" android:layout_toRightOf="@+id/car_ui_scrollbar_thumb" android:layout_above="@+id/car_ui_scrollbar_page_up" android:layout_marginLeft="5dp"/> <ImageView android:id="@+id/car_ui_scrollbar_page_up" android:layout_width="75dp" android:layout_height="75dp" android:focusable="false" android:hapticFeedbackEnabled="false" android:src="@drawable/car_ui_recyclerview_ic_up" android:scaleType="centerInside" android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_centerHorizontal="true" android:layout_above="@+id/car_ui_scrollbar_page_down"/> <ImageView android:id="@+id/car_ui_scrollbar_page_down" android:layout_width="75dp" android:layout_height="75dp" android:focusable="false" android:hapticFeedbackEnabled="false" android:src="@drawable/car_ui_recyclerview_ic_down" android:scaleType="centerInside" android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true"/> </RelativeLayout>
لعرض ملف تنسيق، عليك إضافة جميع أرقام التعريف ومساحة الاسم. إلى
overlay.xml
من RRO. اطّلِع على الملفات أدناه.res/xml/sample_overlay.xml
<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="drawable/car_ui_recyclerview_ic_down" value="@drawable/car_ui_recyclerview_ic_down"/> <item target="drawable/car_ui_recyclerview_ic_up" value="@drawable/car_ui_recyclerview_ic_up"/> <item target="drawable/car_ui_recyclerview_scrollbar_thumb" value="@drawable/car_ui_recyclerview_scrollbar_thumb"/> <item target="id/car_ui_scroll_bar" value="@id/car_ui_scroll_bar"/> <item target="id/car_ui_scrollbar_thumb" value="@id/car_ui_scrollbar_thumb"/> <item target="id/car_ui_scrollbar_track" value="@id/car_ui_scrollbar_track"/> <item target="id/car_ui_scrollbar_page_up" value="@id/car_ui_scrollbar_page_up"/> <item target="id/car_ui_scrollbar_page_down" value="@id/car_ui_scrollbar_page_down"/> <item target="layout/car_ui_recyclerview_scrollbar" value="@layout/car_ui_recyclerview_scrollbar"/> </overlay>
res/drawable/car_ui_recyclerview_ic_up.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,30.83L24,21.66l9.17,9.17L36,28 24,16 12,28z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_ic_down.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,16.42L24,25.59l9.17,-9.17L36,19.25l-12,12 -12,-12z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#0000FF" /> <corners android:radius="100dp"/> </shape>
يُنصح بفحص كيفية تفاعل هذه الملفات.
ولتبسيط الأمر، يتم ترميز الأبعاد والألوان بشكل ثابت. ومع ذلك، من الأفضل التدريب هو الإعلان عن هذه القيم في
dimens.xml
وcolors.xml
أو حتى محددة كملفات ألوان في مجلدres/color/
. للمزيد من المعلومات الرؤية نمط رمز AOSP Java للمساهمينأنشئ تطبيقك وثبِّته على النحو السابق. لقد أنشأت
CarUiRecyclerView
باستخدام شريط تمرير أزرق وأشرطة رمادية
تهانينا! يظهر كلا السهمين أسفل شريط التمرير،
تم تطبيق RRO بنجاح على ملف مورد تنسيق car-ui-lib
باستخدام إصدار Gradle
من خلال "استوديو Android".
![CarUiRecyclerView بشريط تمرير أزرق يتضمّن أشرطة رمادية](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=ar)
عناصر قائمة 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' }
تتم الآن محاذاة العنوان والنص الأساسي إلى اليمين بدلاً من المحاذاة إلى اليسار.
![عنوان ونص محاذاة إلى اليمين](https://source.android.com/static/docs/automotive/images/codelab_16.png?hl=ar)
لم يتم تطبيق RRO على car-ui-lib
إلا باستخدام مكونات AndroidX.
(ConstraintLayout
) عندما كانت سماته متوفّرة في car-ui-lib
.
باسم overlayable.xml
بالإضافة إلى RRO sample_overlay.xml
. من المهم
ممكن أن تفعل شيئًا مشابهًا في تطبيقك. ما عليك سوى إضافة جميع
attrs
مقارنةً بـ overlayable.xml
في تطبيقك، على غرار car-ui-lib
ومع ذلك، ليس من الممكن تشغيل تطبيق RRO باستخدام مكونات AndroidX عندما
يتضمّن التطبيق car-ui-lib
كتبعية في build.gradle
(عندما يستخدم التطبيق
car-ui-lib
). ونظرًا لأن تعيينات السمات قد تم تحديدها بالفعل في
overlayable.xml
في مكتبة car-ui-lib
، وستتم إضافته إلى
سيؤدي استخدام overlayable.xml
في التطبيق مع car-ui-lib
كتبعية إلى
خطأ واحد (mergeDebugResources
) مثل ذلك أدناه. وذلك لأن هذه السمات
متوفّرة في عدة ملفات overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'