Tutarlı, araç içi bilgi-eğlence (IVI) sistemleri başlatmak için car-ui-lib kitaplığını kullanın. Bu codelab'de car-ui-lib ve kitaplıktaki bileşenleri özelleştirmek için çalışma zamanı kaynak katmanlarını (RRO'lar) nasıl kullanabileceğiniz açıklanmaktadır.
Neler öğreneceksiniz?
Nasıl yapılır?
- Android uygulamanıza
car-ui-libbileşenlerini ekleyin. - Android uygulamaları ve RRO'lar oluşturmak için Gradle'ı kullanın.
car-ui-libile RRO'ları kullanma
Bu codelab'de RRO'ların nasıl çalıştığı ayrıntılı olarak açıklanmamaktadır. Daha fazla bilgi için Çalışma zamanında bir uygulamanın kaynaklarının değerini değiştirme ve Çalışma zamanı kaynak yer paylaşımlarıyla ilgili sorunları giderme başlıklı makaleleri inceleyin.
Başlamadan önce
Ön koşullar
Başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:
Komut satırı olan bir bilgisayar (Linux makine, Mac veya Windows Subsystem for Linux'un yüklü olduğu Windows makine).
Makinenize bağlı Android cihaz veya emülatör. Android kaynağını indirme ve Android'i derleme başlıklı makaleleri inceleyin.
RRO'lar hakkında temel bilgi
Yeni bir Android uygulaması oluşturma
Süre: 15 dakika
Bu bölümde yeni bir Android Studio projesi oluşturacaksınız.
Android Studio'da
EmptyActivityiçeren bir uygulama oluşturun.
Şekil 1.Boş Etkinlik Oluşturma Uygulamaya ad verin
CarUiCodelabve Java dilini seçin. İsterseniz dosya konumu da seçebilirsiniz. Kalan ayarlar için varsayılan değerleri kabul edin.
Şekil 2. Uygulamanıza ad verme activity_main.xmlyerine aşağıdaki kod bloğunu ekleyin:<?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>Bu kod bloğunda, tanımlanmamış olan
sample_textdizesi gösteriliyor.sample_textkaynak dizesini ekleyin vestrings.xmldosyanızda "Hello World!" olarak ayarlayın. Bu dosyayı açmak için app > src > main > res > values > strings.xml'i seçin.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiCodelab</string> <string name="sample_text">Hello World!</string> </resources>Uygulamanızı oluşturmak için sağ üstteki yeşil Play (Oynat) düğmesini tıklayın. Bu işlem, Gradle aracılığıyla APK'yı emülatörünüze veya Android cihazınıza otomatik olarak yükler.
Yeni uygulama, emülatörünüzde veya Android cihazınızda otomatik olarak açılır. Aksi takdirde, uygulama başlatıcıdan CarUiCodelab uygulamasını açın.
Şöyle görünür:
Android uygulamanıza car-ui-lib ekleme
Süre: 15 dakika
Uygulamanıza car-ui-lib ekleme:
car-ui-libbağımlılığını projenizinbuild.gradledosyasına eklemek için app > build.gradle'ı seçin. Bağımlılıklarınız aşağıdaki gibi görünmelidir: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' }
Android uygulamanızda car-ui-lib bileşenlerini kullanma
Artık car-ui-lib'niz olduğuna göre uygulamanıza bir araç çubuğu ekleyin.
MainActivity.javadosyanızdaonCreateyönteminin üzerine yazın:@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); }ToolbarControllerdosyasını içe aktardığınızdan emin olun:import com.android.car.ui.core.CarUi; import com.android.car.ui.toolbar.ToolbarController;Theme.CarUi.WithToolbartemasını kullanmak için app > src > main > AndroidManifest.xml'i seçin ve ardındanAndroidManifest.xmlöğesini aşağıdaki gibi görünecek şekilde güncelleyin:<?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>Uygulamayı oluşturmak için daha önce olduğu gibi yeşil Oynat düğmesine basın.
Uygulamanıza RRO'lar ekleme
Süre: 30 dakika
RRO'lar hakkında bilginiz varsa sonraki bölüme, Uygulamanıza izin denetleyicisi ekleme bölümüne gidin. Aksi takdirde, RRO'ların temellerini öğrenmek için Uygulama kaynaklarının değerini çalışma zamanında değiştirme başlıklı makaleyi inceleyin.
Uygulamanıza izin denetleyicisi ekleme
Bir RRO paketinin hangi kaynakları kaplayacağını kontrol etmek için uygulamanızın /res klasörüne overlayable.xml adlı bir dosya ekleyin. Bu dosya, uygulamanız (hedef) ve RRO paketiniz (kaplama) arasında izin denetleyicisi olarak işlev görür.
Uygulamanıza
res/values/overlayable.xmlekleyin ve aşağıdaki içeriği dosyanıza kopyalayın:<?xml version="1.0" encoding="utf-8"?> <resources> <overlayable name="CarUiCodelab"> <policy type="public"> <item type="string" name="sample_text"/> </policy> </overlayable> </resources>sample_textdizesi bir RRO tarafından yerleştirilebildiğinden kaynak adını uygulamanın overlayable.xml dosyasına ekleyin.overlayable.xmldosyanız KESİNLİKLEres/values/içinde bulunmalıdır. Aksi takdirdeOverlayManagerServicebu öğeyi bulamaz.Yerleştirilebilir kaynaklar ve bunların nasıl yapılandırılacağı hakkında daha fazla bilgi edinmek için Yerleştirilebilir kaynakları kısıtlama başlıklı makaleyi inceleyin.
RRO paketi oluşturma
Bu bölümde, yukarıda gösterilen dizeyi "Hello World!" yerine "Hello World RRO" olarak değiştirmek için bir RRO paketi oluşturacaksınız.
Yeni bir proje oluşturmak için Dosya > Yeni > Yeni Proje'yi seçin. RRO paketleri yalnızca kaynak içerdiğinden, Boş Etkinlik yerine Etkinlik Yok'u seçtiğinizden emin olun.
Yapılandırmalarınız, aşağıda gösterilenlere benzer şekilde görünür. Kaydedildikleri konum farklı olabilir:
Yeni
CarUiRROprojesini oluşturduktan sonraAndroidManifest.xmlöğesini değiştirerek projeyi RRO olarak bildirin.<?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>Bu işlem,
@xml/sample_overlayile ilgili bir hataya neden olur.resourcesMapdosyası, hedef paketteki kaynak adlarını RRO paketine eşler.hasCodeişaretininfalseolarak ayarlanması, RRO paketleri için zorunludur. Ayrıca, RRO paketlerinin DEX dosyaları içermesine izin verilmez.Aşağıdaki kod bloğunu
…/res/xml/sample_overlay.xmliçine kopyalayın:<?xml version="1.0" encoding="utf-8"?> <overlay> <item target="string/sample_text" value="@string/sample_text"/> </overlay>sample_textöğesini…/res/values/strings.xmlöğesine ekleme:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">CarUiRRO</string> <string name="sample_text">Hello World RRO</string> </resources>
RRO hedefinizi oluşturmak için yeşil Play düğmesine basarak emülatörünüzde veya Android cihazınızda RRO'nuzun Gradle derlemesini oluşturun.
RRO'nuzun düzgün şekilde yüklendiğini doğrulamak için şu komutu çalıştırın:
shell:~$ adb shell cmd overlay list --user current | grep -i com.example com.example.caruicodelab [ ] com.example.caruirroBu komut, sistemdeki RRO paketlerinin durumu hakkında faydalı bilgiler gösterir.
[ ], RRO'nun yüklendiğini ve etkinleştirilmeye hazır olduğunu gösterir.---, RRO'nun yüklendiğini ancak hatalar içerdiğini gösterir.[X], RRO'nun yüklendiği ve etkinleştirildiği anlamına gelir.
Çalışma zamanı kaynak yer paylaşımınızda hatalar varsa devam etmeden önce Çalışma zamanı kaynak yer paylaşımlarıyla ilgili sorunları giderme başlıklı makaleyi inceleyin.
RRO'yu etkinleştirmek ve etkinleştirildiğini doğrulamak için:
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
Uygulamanız "Hello World RRO" dizesini gösteriyor.
Tebrikler! İlk RRO'nuzu oluşturdunuz.
RRO'ları kullanırken Bağlantı seçenekleri bölümünde açıklanan Android Asset Packaging Tool (AAPT2) --no-resource-deduping ve --no-resource-removal işaretlerini kullanmak isteyebilirsiniz.
Bu codelab'de işaretleri eklemeniz gerekmez ancak kaynakların kaldırılmasını (ve hata ayıklama sorunlarını) önlemek için RRO'larınızda kullanmanızı öneririz. Bunları RRO'nuzun build.gradle dosyasına şu şekilde ekleyebilirsiniz:
android {
…
aaptOptions {
additionalParameters "--no-resource-deduping", "--no-resource-removal"
}
}
Bu işaretler hakkında daha fazla bilgi edinmek için Paketi oluşturma ve AAPT2 başlıklı makalelere bakın.
Android uygulamanızda RRO'ları kullanarak car-ui-lib bileşenlerini değiştirme
Bu sayfada, Android uygulamanızdaki car-ui-lib kitaplığındaki bileşenleri değiştirmek için nasıl çalışma zamanı kaynak yerleşimi (RRO) kullanabileceğiniz açıklanmaktadır.
Araç çubuğunun arka plan rengini ayarlama
Süre: 15 dakika
Araç çubuğunun arka plan rengini değiştirmek için:
RRO uygulamanıza aşağıdaki değeri ekleyin ve kaynağı parlak yeşil (
#0F0) olarak ayarlayın:<?xml version="1.0" encoding="utf-8"?> <resources> <drawable name="car_ui_toolbar_background">#0F0</drawable> </resources>car-ui-libkitaplığındacar_ui_toolbar_backgroundadlı bir kaynak var. Bu kaynak bir RRO'nun yapılandırmasında yer aldığında, yanlış değer hedeflendiği için araç çubuğu değişmez.RRO'nuz için
AndroidManifest.xmliçindetargetNameöğesinicar-ui-lib'ı gösterecek şekilde güncelleyin:… android:targetName="car-ui-lib" …RRO uygulamak istediğiniz her hedef paket için YENİ bir RRO paketi oluşturmanız GEREKİR. Örneğin, iki farklı hedef için yer paylaşımları oluştururken iki yer paylaşımı APK'sı oluşturmanız gerekir.
RRO'yu daha önce olduğu gibi oluşturun, doğrulayın, yükleyin ve etkinleştirin.
Uygulamanız şu şekilde görünür:
RRO düzenleri ve stilleri
Süre: 15 dakika
Bu alıştırmada, daha önce oluşturduğunuz uygulamaya benzer yeni bir uygulama oluşturacaksınız. Bu uygulama, düzenin yerleştirilmesine olanak tanır. Önceki adımları uygulayın veya mevcut uygulamanızı değiştirin.
overlayable.xmldosyasına aşağıdaki satırları eklediğinizden emin olun:<?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.xmlsimgesinin aşağıdaki gibi göründüğünden emin olun:<?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 uygulamanızda bir
res/layout/activity_main.xmloluşturun ve aşağıdakileri ekleyin:<?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>Stilimizi RRO'ya eklemek için
res/values/styles.xmlöğesini güncelleyin:<?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>AndroidManifest.xmliçindekitargetNameöğesini yeni uygulamanızın adına yönlendirecek şekilde değiştirin:… android:targetName="CarUiCodelab" …Kaynakları RRO'nuzdaki
sample_overlay.xmldosyasına ekleyin:<?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>Uygulamayı ve RRO'yu daha önce yaptığınız gibi oluşturup yükleyin (yeşil Play düğmesi). RRO'nuzu etkinleştirdiğinizden emin olun.
Uygulama ve RRO aşağıdaki gibi oluşturulur. Hello World RRO metni yeşildir ve düzen RRO'sunda belirtildiği gibi ortalanmıştır.
Uygulamanıza CarUiRecyclerView ekleme
Süre: 15 dakika
CarUiRecyclerView arayüzü, car-ui-lib kaynakları aracılığıyla özelleştirilmiş bir RecyclerView'ye erişmek için API'ler sağlar. Örneğin, CarUiRecyclerView
kaydırma çubuğunun etkinleştirilip etkinleştirilmeyeceğini belirlemek için çalışma zamanında bir işareti kontrol eder
ve ilgili düzeni seçer.
CarUiRecyclerVieweklemek için onuactivity_main.xmlveMainActivity.javadosyalarınıza ekleyin. Sıfırdan yeni bir uygulama oluşturabilir veya mevcut uygulamayı değiştirebilirsiniz. Mevcut uygulamayı değiştirirsenizoverlayable.xmliçindeki beyan edilmemiş kaynakları kaldırdığınızdan emin olun.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"/>Aşağıdaki hata mesajı gösterilebilir. Bu mesajı görmezden gelebilirsiniz:
Cannot resolve class com.android.car.ui.recyclerview.CarUiRecyclerViewSınıfınız doğru yazıldığı ve
car-ui-libbağımlılık olarak eklendiği sürece APK'nızı oluşturup derleyebilirsiniz. Hatayı kaldırmak için Dosya > Önbellekleri Geçersiz Kıl'ı seçin, ardından Geçersiz Kıl ve Yeniden Başlat'ı tıklayın.Aşağıdakiler
MainActivity.javaalanına eklensin mi?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; }Uygulamanızı eskisi gibi oluşturup yükleyin.
Artık CarUiRecyclerView simgesini görürsünüz:
Kaydırma çubuğunu kaldırmak için RRO kullanma
Süre: 10 dakika
Bu alıştırmada, CarUiRecyclerView öğesinden kaydırma çubuğunu kaldırmak için RRO'nun nasıl kullanılacağı gösterilmektedir.
RRO'nuzda aşağıdaki dosyaları ekleyin ve değiştirin:
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_enablekaynağı,car-ui-libboole kaynağıdır. Bu kaynak,CarUiRecyclerViewiçinde yukarı ve aşağı düğmelerine sahip, otomobil için optimize edilmiş kaydırma çubuğunun bulunup bulunmadığını kontrol eder.falseolarak ayarlandığında,CarUiRecyclerView, AndroidXRecyclerViewgibi davranır.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>
Uygulamanızı eskisi gibi oluşturup yükleyin. Kaydırma çubuğu artık CarUiRecyclerView uygulamasından kaldırıldı:
CarUiRecyclerView kaydırma çubuğunu yerleştirmek için bir düzen kullanın.
Süre: 15 dakika
Bu alıştırmada, CarUiRecyclerView kaydırma çubuğu düzenini değiştireceksiniz.
RRO uygulamanıza aşağıdaki dosyaları ekleyin ve bu dosyalarda değişiklik yapın.
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>Bir düzen dosyasını yerleştirmek için RRO'nuzun
overlay.xmlbölümüne tüm kimlikleri ve ad alanı özelliklerini eklemeniz gerekir. Aşağıdaki dosyalara bakın.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>Bu dosyaların nasıl etkileşim kurduğunu incelemeniz önerilir.
Kolaylık sağlamak için boyutlar ve renkler sabit kodlanmıştır. Ancak bu değerleri
dimens.xmlvecolors.xmliçinde bildirmek veyares/color/klasöründe renk dosyaları olarak belirtmek en iyi uygulamadır. Daha fazla bilgi edinmek için AOSP Java code style for contributors (Katkıda bulunanlar için AOSP Java kod stili) başlıklı makaleyi inceleyin.Uygulamanızı eskisi gibi oluşturup yükleyin. Mavi kaydırma çubuğu ve gri raylarla
CarUiRecyclerViewoluşturmuş olabilirsiniz.
Tebrikler! Her iki ok da kaydırma çubuğunun en altında görünür. Android Studio üzerinden Gradle derleme sistemini kullanarak car-ui-lib düzen kaynak dosyasına başarıyla RRO uyguladınız.
RRO Liste öğeleri
Süre: 15 dakika
Bu noktaya kadar, framework bileşenlerini (AndroidX değil) kullanarak car-ui-lib bileşenlerine bir RRO uyguladınız. Bir RRO'da AndroidX bileşenlerini kullanmak için bu bileşenin bağımlılıklarını hem uygulamaya hem de RRO'ya eklemeniz gerekir. build.gradle. Ayrıca, bu bileşenin attrs öğesini uygulamanızdaki overlayable.xml öğesine ve RRO'nuzdaki sample_overlay.xml öğesine de eklemeniz gerekir.
Kitaplığımız (car-ui-lib), ConstraintLayout'nin yanı sıra diğer AndroidX bileşenlerini de kullandığı için overlayable.xml şu şekilde görünebilir:
<?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>
CarUiRecyclerViewiçindeki liste öğelerinin düzeniniConstraintLayoutkullanarak değiştirin. RRO'nuzda aşağıdaki dosyaları ekleyin veya değiştirin: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, uygulamanın bağımlılıkları olarak dahil edilmeyen çeşitli bileşenlere/kaynaklara referans veriyor. Bunlarcar-ui-libkaynaklarıdır. Bu sorunu düzeltmek içincar-ui-liböğesiniapp/build.gradlebölümünde RRO uygulamanıza bağımlılık olarak ekleyebilirsiniz: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' }
Başlık ve gövde artık sola değil sağa hizalanıyor.
Yalnızca car-ui-lib adlı dosyada ve RRO sample_overlay.xml'da özellikleri bulunduğunda car-ui-lib için AndroidX bileşenleri kullanılarak RRO uyguladık
(ConstraintLayout).overlayable.xml Benzer bir işlemi kendi uygulamanızda da yapabilirsiniz. attrs'ya benzer şekilde, uygulamanızın overlayable.xml bölümüne ilgili tüm attrs öğelerini eklemeniz yeterlidir.car-ui-lib
Ancak, uygulama build.gradle içinde bağımlılık olarak car-ui-lib içerdiğinde (uygulama car-ui-lib bileşenlerini kullandığında) AndroidX bileşenlerini kullanan bir uygulamaya RRO uygulamak mümkün değildir. Özellik eşlemeleri car-ui-lib kitaplığının overlayable.xml içinde zaten tanımlandığından, bunları car-ui-lib bağımlılığıyla uygulamanızın overlayable.xml dosyasına eklemek aşağıdaki gibi bir mergeDebugResources hatasına neden olur. Bunun nedeni, bu özelliklerin birden fazla overlayable.xml dosyasında bulunmasıdır:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'