אפשר להשתמש בספרייה car-ui-lib
כדי להפעיל מידע ובידור באופן עצמאי ברכב
ו-IVI). ה-Codelab הזה מציג את car-ui-lib
ואיך אפשר
להשתמש בשכבות-על של משאבים בזמן ריצה (RRO) כדי להתאים אישית את הרכיבים בספרייה.
מה תלמדו
איך עושים את זה:
- הכללת רכיבי
car-ui-lib
באפליקציה שלך ל-Android. - ניתן להשתמש ב-Gradle כדי ליצור אפליקציות ל-Android והודעות RRO.
- אפשר להשתמש ב-RRO עם
car-ui-lib
.
ה-Codelab הזה לא מפרט איך פועלים ה-RRO. צפייה לשנות את הערך של המשאבים של אפליקציה בזמן הריצה וגם פתרון בעיות בשכבות-על של משאבים בזמן ריצה למידע נוסף.
לפני שמתחילים
דרישות מוקדמות
לפני שמתחילים, חשוב לוודא שיש לכם:
מחשב עם שורת פקודה (מכונת Linux, Mac או מחשב Windows עם מערכת משנה של Windows ל-Linux).
אמולטור או מכשיר Android שמחוברים למחשב. צפייה מורידים את המקור של Android ואז לבניית Android.
ידע בסיסי בנושא RRO.
איך יוצרים אפליקציה חדשה ל-Android
משך זמן: 15 דקות
בקטע הזה יוצרים פרויקט Android Studio חדש.
ב-Android Studio, יוצרים אפליקציה באמצעות
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
. כדי לפתוח את הקובץ הזה, בוחרים באפשרות אפליקציה > מקור > ראשי > res > ערכים > string.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 שלך באמצעות גרדה.
האפליקציה החדשה אמורה להיפתח באופן אוטומטי באמולטור או במכשיר Android שלכם. אם המיקום
לא, צריך לפתוח את האפליקציה CarUiCodelab
במרכז האפליקציות, שמותקן עכשיו.
כך הוא נראה:
![פתיחת אפליקציה חדשה של CarUiCodelab](https://source.android.com/static/docs/automotive/images/codelab_04.png?hl=he)
הוספת 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
, מחליפים את ה-methodonCreate
:@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 דקות
אם אתם מכירים את ה-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, צריך לכלול את שם המשאב בקובץ Sitelinkable.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, לוחצים על לחצן Play הירוק כדי ליצור 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=he)
מזל טוב! יצרת את ה-RRO הראשון שלך.
כשמשתמשים בשגיאות RRO, כדאי להשתמש בכלי לאריזת הנכסים של Android (AAPT2)
דגלים --no-resource-deduping
ו---no-resource-removal
שמתוארים ב
אפשרויות קישור.
אין צורך להוסיף את הדגלים ב-Codelab הזה, אבל מומלץ להשתמש בהם
ב-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=he)
פריסות וסגנונות של 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 מעובדים באופן הבא. טקסט RRO של Hello World הוא ירוק ממרכזת כפי שמצוין ב-RRO של הפריסה.
![שלום עולם RRO](https://source.android.com/static/docs/automotive/images/codelab_11.png?hl=he)
הוספת CarUiRecyclerView לאפליקציה
משך זמן: 15 דקות
הממשק של CarUiRecyclerView
מספק ממשקי API כדי לגשת ל-RecyclerView
שמותאם אישית באמצעות משאבים של car-ui-lib
. לדוגמה, CarUiRecyclerView
.
בודק דגל בזמן ריצה כדי לקבוע אם סרגל הגלילה צריך להיות מופעל או לא
ובוחר את הפריסה המתאימה.
![CarUiRecyclerViewContainer](https://source.android.com/static/docs/automotive/images/codelab_12.png?hl=he)
כדי להוסיף
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 > (קובץ >) מבטלים את המטמון ואז לוחצים על ביטול והפעלה מחדש.הוספת הפריטים הבאים אל
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=he)
שימוש ב-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 ללא סרגל גלילה](https://source.android.com/static/docs/automotive/images/codelab_14.png?hl=he)
שימוש בפריסה כדי להוסיף שכבת-על לסרגל הגלילה של 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
באמצעות גרסת ה-build של Gradle
במערכת באמצעות Android Studio.
![CarUiRecyclerView עם סרגל גלילה כחול ומסילות אפורות](https://source.android.com/static/docs/automotive/images/codelab_15.png?hl=he)
פריטי רשימה של RRO
משך זמן: 15 דקות
עד עכשיו, החלתם RRO על רכיבים של car-ui-lib
באמצעות framework
רכיבים (לא 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=he)
החלנו 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'