استخدم مكتبة car-ui-lib
لإطلاق أنظمة المعلومات والترفيه (IVI) المتسقة ذاتيًا داخل السيارة. يقدم لك هذا الدرس التطبيقي حول التعليمات البرمجية car-ui-lib
وكيف يمكنك استخدام تراكبات موارد وقت التشغيل (RROs) لتخصيص المكونات في المكتبة.
ما ستتعلمه
كيف:
- قم بتضمين مكونات
car-ui-lib
في تطبيق Android الخاص بك. - استخدم Gradle لإنشاء تطبيقات Android وRROs.
- استخدم RROs مع
car-ui-lib
.
لا يقدم هذا الدرس التطبيقي حول التعليمات البرمجية تفاصيل حول كيفية عمل RROs. راجع تغيير قيمة موارد التطبيق في وقت التشغيل واستكشاف أخطاء تراكبات موارد وقت التشغيل وإصلاحها لمعرفة المزيد.
قبل ان تبدا
المتطلبات الأساسية
قبل البدء، تأكد من أن لديك:
جهاز كمبيوتر مزود بسطر الأوامر (جهاز Linux أو Mac أو جهاز يعمل بنظام Windows مع نظام Windows الفرعي لنظام التشغيل Linux).
جهاز Android أو المحاكي المتصل بجهازك. راجع تنزيل مصدر Android وإنشاء Android .
المعرفة الأساسية بـ RROs.
إنشاء تطبيق أندرويد جديد
المدة: 15 دقيقة
في هذا القسم، يمكنك إنشاء مشروع Android Studio جديد.
في Android Studio، قم بإنشاء تطبيق باستخدام
EmptyActivity
.قم بتسمية التطبيق
CarUiCodelab
ثم حدد لغة Java. يمكنك أيضًا تحديد موقع الملف إذا رغبت في ذلك. اقبل القيم الافتراضية للإعدادات المتبقية.استبدل
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 > value > strings.xml .<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>
لإنشاء تطبيقك، انقر فوق زر التشغيل الأخضر في الجزء العلوي الأيسر. يؤدي القيام بذلك إلى تثبيت ملف APK تلقائيًا على المحاكي أو جهاز Android الخاص بك من خلال Gradle.
من المفترض أن يتم فتح التطبيق الجديد تلقائيًا على جهاز المحاكي أو جهاز Android. إذا لم يكن الأمر كذلك، فافتح تطبيق CarUiCodelab
من مشغل التطبيق المثبت الآن. يبدو مثل هذا:
أضف car-ui-lib إلى تطبيق Android الخاص بك
المدة: 15 دقيقة
أضف car-ui-lib
إلى تطبيقك:
لإضافة تبعية
car-ui-lib
إلى ملفbuild.gradle
الخاص بمشروعك، حدد app > build.gradle . يجب أن تظهر تبعياتك بالشكل التالي:dependencies { implementation 'com.android.car.ui:car-ui-lib:2.0.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' }
استخدم مكونات car-ui-lib في تطبيق Android الخاص بك
الآن بعد أن أصبح لديك car-ui-lib
، أضف شريط أدوات إلى تطبيقك.
في ملف
MainActivity.java
، قم بالكتابة فوق طريقةonCreate
:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the toolbar controller instance. ToolbarController toolbar = CarUi.getToolbar(this); // Set the title on toolbar. toolbar.setTitle(getTitle()); // Set the logo to be shown with the title. toolbar.setLogo(R.mipmap.ic_launcher_round); }
تأكد من استيراد
ToolbarController
:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;
لاستخدام سمة
Theme.CarUi.WithToolbar
، حدد 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>
لإنشاء التطبيق، اضغط على زر التشغيل الأخضر كما كان من قبل.
أضف RROs إلى تطبيقك
المدة: 30 دقيقة
إذا كنت معتادًا على RROs، فانتقل إلى القسم التالي، إضافة وحدة تحكم الأذونات إلى تطبيقك . بخلاف ذلك، للتعرف على أساسيات RROs، راجع تغيير قيمة موارد التطبيق في وقت التشغيل .
أضف وحدة تحكم الأذونات إلى تطبيقك
للتحكم في الموارد التي تغطيها حزمة RRO، أضف ملفًا باسم overlayable.xml
إلى مجلد /res
الخاص بالتطبيق. يعمل هذا الملف كوحدة تحكم في الأذونات بين تطبيقك ( الهدف ) وحزمة RRO ( التراكب ).
أضف
res/values/overlayable.xml
إلى تطبيقك وانسخ المحتوى التالي إلى ملفك:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>
نظرًا لأن السلسلة
sample_text
يجب أن تكون قابلة للتراكب بواسطة RRO، قم بتضمين اسم المورد في overlayable.xml الخاص بالتطبيق.يجب أن يكون ملف
overlayable.xml
موجودًا فيres/values/
. إذا لم يكن الأمر كذلك، فلن تتمكنOverlayManagerService
من تحديد موقعه.لمعرفة المزيد حول الموارد القابلة للتراكب وكيف يمكن تكوينها، راجع تقييد الموارد القابلة للتراكب .
قم بإنشاء حزمة RRO
في هذا القسم، يمكنك إنشاء حزمة RRO لتغيير السلسلة المعروضة أعلاه من "Hello World!" إلى "Hello World RRO".
لإنشاء مشروع جديد، حدد ملف > جديد > مشروع جديد . تأكد من تحديد "لا يوجد نشاط" بدلاً من "نشاط فارغ" لأن حزم RRO تحتوي على الموارد فقط.
تظهر التكوينات الخاصة بك بشكل مشابه لتلك الموضحة أدناه. قد يختلف الموقع الذي يتم حفظها فيه:
بعد إنشاء مشروع
CarUiRRO
الجديد، قم بإعلان المشروع باعتباره RRO عن طريق تعديلAndroidManifest.xml
.<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.caruirro"> <application android:hasCode="false" /> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/> <overlay android:targetPackage="com.example.caruicodelab" android:targetName="CarUiCodelab" android:isStatic="false" android:resourcesMap="@xml/sample_overlay" /> </manifest>
يؤدي القيام بذلك إلى إنشاء خطأ في
@xml/sample_overlay
. يقوم ملفresourcesMap
بتعيين أسماء الموارد من الحزمة الهدف إلى حزمة RRO.انسخ كتلة التعليمات البرمجية التالية إلى
…/res/xml/sample_overlay.xml
:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>
أضف
sample_text
إلى…/res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
لإنشاء هدف RRO الخاص بك، اضغط على زر التشغيل الأخضر لإنشاء إصدار Gradle لـ RRO الخاص بك على المحاكي أو جهاز Android.
للتحقق من تثبيت RRO بشكل صحيح، قم بتشغيل:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirro
يعرض هذا الأمر معلومات مفيدة حول حالة حزم RRO على النظام.
-
[ ]
يشير إلى أن RRO قد تم تثبيته وجاهز للتنشيط. -
---
يشير إلى أنه تم تثبيت RRO ولكنه يحتوي على أخطاء. -
[X]
يعني أنه تم تثبيت RRO وتنشيطه.
إذا كان RRO الخاص بك يحتوي على أخطاء، فراجع استكشاف أخطاء تراكبات موارد وقت التشغيل وإصلاحها قبل المتابعة.
-
لتمكين RRO والتحقق من تمكينه:
shell:~$ adb shell cmd overlay enable --user current com.example.caruirro shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [x] com.example.caruirro
يعرض تطبيقك السلسلة "Hello World RRO".
تهانينا! لقد قمت بإنشاء أول RRO الخاص بك.
عند استخدام RROs، قد ترغب في استخدام علامتي Android Asset Packaging Tool (AAPT2) --no-resource-deduping
و --no-resource-removal
الموضحتين في خيارات الارتباط . ليس من الضروري إضافة العلامات في هذا الدرس التطبيقي حول التعليمات البرمجية، ولكننا نقترح عليك استخدامها في RROs لتجنب إزالة الموارد (وتصحيح الأخطاء). يمكنك إضافتها إلى ملف build.gradle
الخاص بـ RRO الخاص بك مثل هذا:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
لمعرفة المزيد حول هذه العلامات، راجع إنشاء الحزمة و AAPT2 .
قم بتعديل مكونات car-ui-lib
باستخدام RROs في تطبيق 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 والتحقق منه وتثبيته وتمكينه بنفس الطريقة السابقة.
يظهر تطبيقك هكذا:
تخطيطات وأنماط RRO
المدة: 15 دقيقة
في هذا التمرين، تقوم بإنشاء تطبيق جديد مشابه للتطبيق الذي قمت بإنشائه سابقًا. يسمح هذا التطبيق بتراكب التخطيط. اتبع نفس الخطوات السابقة، أو قم بتعديل تطبيقك الحالي.
تأكد من إضافة الأسطر التالية إلى
overlayable.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> <item type="layout" name="activity_main"/> <item type="id" name="textView"/> </policy> </overlayable> </resources>
تأكد من ظهور
activity_main.xml
كما يلي:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
في تطبيق RRO الخاص بك، قم بإنشاء
res/layout/activity_main.xml
وأضف ما يلي:<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sample_text" android:textAppearance="@style/TextAppearance.CarUi" android:layout_gravity="center_vertical|center_horizontal"/> </FrameLayout>
قم بتحديث
res/values/styles.xml
لإضافة النمط الخاص بنا إلى RRO:<?xml version="1.0" encoding="utf-8"?> <resources> <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault"> <item name="android:textColor">#0f0</item> <item name="android:textSize">100sp</item> </style> </resources>
قم بتغيير
targetName
فيAndroidManifest.xml
للإشارة إلى اسم تطبيقك الجديد:… android:targetName="CarUiCodelab" …
أضف الموارد إلى ملف
sample_overlay.xml
في RRO الخاص بك:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> <item target="id/textView" value="@id/textView"/> <item target="layout/activity_main" value="@layout/activity_main"/> </overlay>
قم ببناء التطبيق وRRO وتثبيته بنفس الطريقة السابقة (زر التشغيل الأخضر). تأكد من تمكين RRO الخاص بك.
يتم عرض التطبيق وRRO على النحو التالي. يظهر نص Hello World RRO باللون الأخضر ويتم توسيطه كما هو محدد في تخطيط RRO.
أضف CarUiRecyclerView إلى تطبيقك
المدة: 15 دقيقة
توفر واجهة CarUiRecyclerView
واجهات برمجة التطبيقات للوصول إلى 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 الخاص بك وتجميعه. لإزالة الخطأ، حدد ملف > إبطال ذاكرة التخزين المؤقت ثم انقر فوق إبطال وإعادة التشغيل.أضف ما يلي إلى
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.xml
الخاص بـ RRO الخاص بك. انظر الملفات أدناه.res/xml/sample_overlay.xml
<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="drawable/car_ui_recyclerview_ic_down" value="@drawable/car_ui_recyclerview_ic_down"/> <item target="drawable/car_ui_recyclerview_ic_up" value="@drawable/car_ui_recyclerview_ic_up"/> <item target="drawable/car_ui_recyclerview_scrollbar_thumb" value="@drawable/car_ui_recyclerview_scrollbar_thumb"/> <item target="id/car_ui_scroll_bar" value="@id/car_ui_scroll_bar"/> <item target="id/car_ui_scrollbar_thumb" value="@id/car_ui_scrollbar_thumb"/> <item target="id/car_ui_scrollbar_track" value="@id/car_ui_scrollbar_track"/> <item target="id/car_ui_scrollbar_page_up" value="@id/car_ui_scrollbar_page_up"/> <item target="id/car_ui_scrollbar_page_down" value="@id/car_ui_scrollbar_page_down"/> <item target="layout/car_ui_recyclerview_scrollbar" value="@layout/car_ui_recyclerview_scrollbar"/> </overlay>
res/drawable/car_ui_recyclerview_ic_up.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,30.83L24,21.66l9.17,9.17L36,28 24,16 12,28z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_ic_down.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path android:pathData="M14.83,16.42L24,25.59l9.17,-9.17L36,19.25l-12,12 -12,-12z" android:fillColor="#0000FF"/> </vector>
res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#0000FF" /> <corners android:radius="100dp"/> </shape>
يُقترح فحص كيفية تفاعل هذه الملفات.
من أجل البساطة، يتم ترميز الأبعاد والألوان. ومع ذلك، فإن أفضل الممارسات هي الإعلان عن هذه القيم في
dimens.xml
وcolors.xml
أو حتى تعيينها كملفات ملونة في المجلدres/color/
. لمعرفة المزيد، راجع نمط كود Java AOSP للمساهمين .قم ببناء وتثبيت التطبيق الخاص بك كما كان من قبل. لقد قمت بإنشاء
CarUiRecyclerView
بشريط تمرير أزرق وقضبان رمادية.
تهانينا! يظهر كلا السهمين على طول الجزء السفلي من شريط التمرير، لقد نجحت في تطبيق RRO على ملف مورد تخطيط car-ui-lib
باستخدام نظام بناء Gradle من خلال Android Studio.
عناصر قائمة 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
.
ومع ذلك، ليس من الممكن 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'