השתמש בספריית car-ui-lib
כדי להשיק מערכות מידע בידור (IVI) עקביות בעצמן, בתוך הרכב. מעבדת קוד זה מציגה לך את car-ui-lib
וכיצד אתה יכול להשתמש בשכבות-על של משאבי ריצה (RRO) כדי להתאים אישית רכיבים בספרייה.
מה תלמד
איך ל:
- כלול רכיבי
car-ui-lib
באפליקציית Android שלך. - השתמש ב-Gradle כדי לבנות אפליקציות Android ו-RROs.
- השתמש ב-RROs עם
car-ui-lib
.
מעבד קוד זה אינו מפרט כיצד פועלים RRO. ראה שינוי הערך של משאבי אפליקציה בזמן ריצה ופתרון בעיות בשכבות-על של משאבי זמן ריצה למידע נוסף.
לפני שאתה מתחיל
דרישות מוקדמות
לפני שתתחיל, ודא שיש לך:
מחשב עם שורת פקודה (מכונת Linux, Mac או Windows עם מערכת המשנה של Windows עבור לינוקס).
מכשיר אנדרואיד או אמולטור מחוברים למכשיר שלך. ראה הורדת מקור אנדרואיד ובניית אנדרואיד .
ידע בסיסי ב-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
שלך. כדי לפתוח קובץ זה, בחר אפליקציה > src > main > res > ערכים > 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 באופן אוטומטי באמולטור או במכשיר האנדרואיד שלך דרך Gradle.
האפליקציה החדשה אמורה להיפתח אוטומטית באמולטור או במכשיר האנדרואיד שלך. אם לא, פתח את אפליקציית 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
, בחר אפליקציה > 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 שלך באמולטור או במכשיר האנדרואיד שלך.
כדי לוודא שה-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. לדוגמה, בעת יצירת שכבות-על עבור שני יעדים שונים, עליך ליצור שני אפקסים של שכבת-על.
בנה, אמת, התקן והפעל את ה-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
מספק ממשקי API לגישה ל- RecyclerView
המותאם אישית באמצעות משאבי car-ui-lib
. לדוגמה, CarUiRecyclerView
בודק דגל בזמן ריצה כדי לקבוע אם יש להפעיל את פס הגלילה או לא ובוחר את הפריסה המתאימה.
כדי להוסיף
CarUiRecyclerView
, הוסף אותו לקבציactivity_main.xml
ו-MainActivity.java
שלך. אתה יכול ליצור אפליקציה חדשה מאפס או לשנות את האפליקציה הקיימת. אם תשנה את האפליקציה הקיימת, הקפד להסיר משאבים לא מוכרזים מ-overlayable.xml
.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <com.android.car.ui.recyclerview.CarUiRecyclerView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
עלולה להופיע השגיאה הבאה, שתוכל להתעלם ממנה:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerView
כל עוד הכיתה שלך מאויתת נכון והוספת
car-ui-lib
כתלות, אתה יכול לבנות ולהרכיב את ה-apk שלך. כדי להסיר את השגיאה, בחר File > Invalidate Caches ולאחר מכן לחץ על Invalidate and Restart.הוסף את הדברים הבאים ל-
MainActivity.java
package com.example.caruicodelab; import android.app.Activity; import android.os.Bundle; import com.android.car.ui.core.CarUi; import com.android.car.ui.recyclerview.CarUiContentListItem; import com.android.car.ui.recyclerview.CarUiListItem; import com.android.car.ui.recyclerview.CarUiListItemAdapter; import com.android.car.ui.recyclerview.CarUiRecyclerView; import com.android.car.ui.toolbar.ToolbarController; import java.util.ArrayList; /** Activity with a simple car-ui layout. */ public class MainActivity extends Activity { private final ArrayList<CarUiListItem> mData = new ArrayList<>(); private CarUiListItemAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ToolbarController toolbar = CarUi.getToolbar(this); toolbar.setTitle(getTitle()); toolbar.setLogo(R.mipmap.ic_launcher_round); CarUiRecyclerView recyclerView = findViewById(R.id.list); mAdapter = new CarUiListItemAdapter(generateSampleData()); recyclerView.setAdapter(mAdapter); } private ArrayList<CarUiListItem> generateSampleData() { for (int i = 0; i < 20; i++) { CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.ICON); item.setTitle("Title " + i); item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT); item.setIcon(getDrawable(R.drawable.ic_launcher_foreground)); item.setBody("body " + i); mData.add(item); } return mData; }
בנה והתקן את האפליקציה שלך כמו קודם.
כעת אתה רואה CarUiRecyclerView
:
השתמש ב-RRO כדי להסיר את פס הגלילה
משך: 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
). מכיוון שמיפוי המאפיינים כבר הוגדרו בספריית car-ui-lib
overlayable.xml
, הוספתם ל- overlayable.xml
של האפליקציה שלך עם car-ui-lib
כתלות תגרום לשגיאה של mergeDebugResources
כמו זו למטה. הסיבה לכך היא שתכונות אלה קיימות במספר קובצי overlayable.xml
:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'