Aşağıdaki materyal, uygulama geliştiriciler içindir.
Uygulamanızın dönen reklamları desteklemesi için ŞARTLAR:
- İlgili etkinlik düzenine bir
FocusParkingView
yerleştirin. - Odaklanabilir (veya odaklanamayan) görünümlerden emin olun.
FocusParkingView
dışındaki tüm odaklanılabilir görünümlerinizi sarmalamak içinFocusArea
kullanın.
Bu görevlerin her biri, ortamınızı döner ekrana sahip uygulamalar geliştirmek için ayarladıktan sonra aşağıda ayrıntılı olarak açıklanmıştır.
Döner kontrol cihazı ayarlama
Döner kontrollü uygulamalar geliştirmeye başlamadan önce bir döner kontrol cihazına veya stand-in'e ihtiyacınız vardır. Aşağıda açıklanan seçenekleri kullanabilirsiniz.
Emülatör
source build/envsetup.sh && lunch car_x86_64-userdebug m -j emulator -wipe-data -no-snapshot -writable-system
aosp_car_x86_64-userdebug
simgesini de kullanabilirsiniz.
Taklit edilen döner kontrolöre erişmek için:
- Araç çubuğunun alt kısmındaki üç noktaya dokunun:
Şekil 1. Taklit edilen döner kontrol düğmesine erişim - Genişletilmiş kontroller penceresinde Araba döner düğmesi'ni seçin:
Şekil 2. Araba dönen simgesini seçin
USB klavye
- Android Automotive OS (AAOS) çalıştıran cihazınıza bir USB klavye takın. Bazı durumlarda bu, ekran klavyesinin görünmesini engeller.
userdebug
veyaeng
derlemesi kullanın.- Önemli etkinlik filtrelemeyi etkinleştirin:
adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
- Her işleme karşılık gelen anahtarı bulmak için aşağıdaki tabloya bakın:
Anahtar Döndürme işlemi SORU Saat yönünün tersine döndürme E Saat yönünde döndürme A Sola sürükle D Sağa sürükle W Yukarı sürükle S Aşağı sürükle F veya virgül Orta düğme R veya Esc Geri düğmesi
ADB komutları
Döner giriş etkinlikleri eklemek için car_service
komutlarını kullanabilirsiniz. Bu komutlar, Android Automotive OS (AAOS) çalıştıran cihazlarda veya bir emülatörde çalıştırılabilir.
car_service komutları | Çevirmeli giriş |
---|---|
adb shell cmd car_service inject-rotary |
Saat yönünün tersine döndürme |
adb shell cmd car_service inject-rotary -c true |
Saat yönünde döndürme |
adb shell cmd car_service inject-rotary -dt 100 50 |
Saat yönünün tersine birden çok kez döndürme (100 ms önce ve 50 ms önce) |
adb shell cmd car_service inject-key 282 |
Sola sürükle |
adb shell cmd car_service inject-key 283 |
Sağa sürükle |
adb shell cmd car_service inject-key 280 |
Yukarı sürükle |
adb shell cmd car_service inject-key 281 |
Aşağı sürükle |
adb shell cmd car_service inject-key 23 |
Orta düğme tıklaması |
adb shell input keyevent inject-key 4 |
Geri düğmesi tıklaması |
OEM döner kontrol düğmesi
Döner kontrol cihazı donanımınız çalışır durumdayken bu en gerçekçi seçenektir. Özellikle hızlı rotasyonu test etmek için yararlıdır.
FocusParkingView
FocusParkingView
, Araba Kullanıcı Arayüzü Kitaplığı'ndaki (car-ui-library) şeffaf bir görünümdür.
RotaryService
, döner kontrol cihazı gezinmesini desteklemek için bu özelliği kullanır.
FocusParkingView
, düzendeki ilk odaklanılabilir görünüm olmalıdır. Tüm FocusArea
değerlerinin dışında yerleştirilmelidir. Her pencerede bir FocusParkingView
olmalıdır. FocusParkingView
içeren car-ui-library temel düzenini zaten kullanıyorsanız başka bir FocusParkingView
eklemeniz gerekmez. Aşağıda, RotaryPlayground
içindeki FocusParkingView
örneği gösterilmektedir.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.android.car.ui.FocusParkingView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
FocusParkingView
'ye ihtiyacınız olan nedenler şunlardır:
- Android, odak başka bir pencerede ayarlandığında odağı otomatik olarak temizlemez. Önceki pencerede odak noktasını temizlemeye çalışırsanız Android, söz konusu pencerede bir görünümü yeniden odaklar. Bu da iki pencerenin aynı anda odaklanmasına neden olur. Her pencereye bir
FocusParkingView
eklemek bu sorunu düzeltebilir. Bu görünüm şeffaftır ve varsayılan odak vurgulaması devre dışıdır. Böylece, odakta olup olmadığına bakılmaksızın kullanıcı tarafından görülemez. Odağı alabilir. BöyleceRotaryService
, odak vurgusunu kaldırmak için odağı üzerinde park edebilir. - Geçerli pencerede yalnızca bir
FocusArea
varsaFocusArea
'te denetleyiciyi döndürmek,RotaryService
'ün odağı sağdaki görünümden soldaki görünüme (veya tam tersi) taşımasına neden olur. Bu görünümü her pencereye eklemek sorunu çözebilir.RotaryService
, odak hedefininFocusParkingView
olduğunu belirlediğinde, sarma işleminin gerçekleşmek üzere olduğunu belirleyebilir. Bu noktada, odağı hareket ettirmeyerek sarma işlemini önler. - Döner kontrol bir uygulamayı başlattığında Android, her zaman
FocusParkingView
olan ilk odaklanılabilir görünüme odaklanır.FocusParkingView
odaklanılacak en uygun görünümü belirler ve ardından odaklanmayı uygular.
Odaklanılabilir görünümler
RotaryService
, Android çerçevesinin telefonlarda fiziksel klavye ve D-pad'lerin bulunduğu zamanlardan beri kullanılan mevcut görüntü odak kavramına dayanır.
Mevcut android:nextFocusForward
özelliği, döner için yeniden tasarlanmıştır (FocusArea özelleştirme bölümüne bakın). Ancak android:nextFocusLeft
, android:nextFocusRight
, android:nextFocusUp
ve android:nextFocusDown
özellikleri için bu yapılmamıştır.
RotaryService
yalnızca odaklanılabilir görüntülemelere odaklanır. Button
gibi bazı görünümler genellikle odaklanılabilir. TextView
ve ViewGroup
gibi diğer karakterler genellikle bu şekilde gösterilmez. Tıklanabilir görünümler otomatik olarak odaklanılabilirdir ve görünümler, tıklama dinleyicileri olduğunda otomatik olarak tıklanabilirdir. Bu otomatik mantık, istenen odaklanılabilirlikle sonuçlanırsa görünümün odaklanılabilirliğini açıkça ayarlamanız gerekmez. Otomatik mantık, istenen odaklanılabilirliği sağlamazsa android:focusable
özelliğini true
veya false
olarak ayarlayın ya da görünümün odaklanılabilirliğini View.setFocusable(boolean)
ile programatik olarak ayarlayın. RotaryService
'ün bir görüntüye odaklanabilmesi için görüntünün aşağıdaki koşulları karşılaması GEREKİR:
- Odaklanılabilir
- Etkin
- Gösteriliyor
- Genişlik ve yükseklik için sıfır olmayan değerlere sahip olmalıdır.
Bir görünüm tüm bu koşulları karşılamıyorsa (ör. odaklanılabilir ancak devre dışı bırakılmış bir düğme) kullanıcı, döner kontrolü kullanarak bu görünüme odaklanamaz. Devre dışı görünümlere odaklanmak istiyorsanız Android'in devre dışı olarak değerlendirmesini belirtmeden görünümün nasıl görüneceğini kontrol etmek için android:state_enabled
yerine özel bir durum kullanmayı düşünebilirsiniz. Uygulamanız, dokunulduğunda görünümün neden devre dışı bırakıldığını kullanıcıya bildirebilir. Bunu nasıl yapacağınız sonraki bölümde açıklanmıştır.
Özel durum
Özel durum eklemek için:
- Görünümünüze özel özellik eklemek için Örneğin,
CustomView
görünüm sınıfınastate_rotary_enabled
özel durumu eklemek için:<declare-styleable name="CustomView"> <attr name="state_rotary_enabled" format="boolean" /> </declare-styleable>
- Bu durumu izlemek için erişim yöntemleriyle birlikte görünümünüze bir örnek değişkeni ekleyin:
private boolean mRotaryEnabled; public boolean getRotaryEnabled() { return mRotaryEnabled; } public void setRotaryEnabled(boolean rotaryEnabled) { mRotaryEnabled = rotaryEnabled; }
- Görüntünüz oluşturulduğunda özelliğinizin değerini okumak için:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView); mRotaryEnabled = a.getBoolean(R.styleable.CustomView_state_rotary_enabled);
- Görüntüleme sınıfınızda
onCreateDrawableState()
yöntemini geçersiz kılın ve ardından uygun olduğunda özel durumu ekleyin. Örnek:@Override protected int[] onCreateDrawableState(int extraSpace) { if (mRotaryEnabled) extraSpace++; int[] drawableState = super.onCreateDrawableState(extraSpace); if (mRotaryEnabled) { mergeDrawableStates(drawableState, { R.attr.state_rotary_enabled }); } return drawableState; }
- Görünümünüzün tıklama işleyicisinin durumuna bağlı olarak farklı şekilde çalışmasını sağlayın. Örneğin, tıklama işleyici hiçbir şey yapmayabilir veya
mRotaryEnabled
false
olduğunda bir pop-up gösterebilir. - Düğmenin devre dışı görünmesi için görünümünüzün arka planı çizilebilir alanında
android:state_enabled
yerineapp:state_rotary_enabled
kullanın. Henüz yoksa şunları eklemeniz gerekir:xmlns:app="http://schemas.android.com/apk/res-auto"
- Görüntünüz herhangi bir düzende devre dışıysa
android:enabled="false"
değeriniapp:state_rotary_enabled="false"
ile değiştirin ve ardından yukarıdaki gibiapp
ad alanını ekleyin. - Görüntünüz programatik olarak devre dışı bırakıldıysa
setEnabled()
ile başlayan çağrılarısetRotaryEnabled()
ile başlayan çağrılarla değiştirin.
FocusArea
Gezinmeyi kolaylaştırmak ve diğer uygulamalarla tutarlı olmak için odaklanılabilir görünümleri bloklara ayırmak üzere FocusAreas
simgesini kullanın. Örneğin, uygulamanızda araç çubuğu varsa araç çubuğu, uygulamanızın geri kalanından ayrı bir FocusArea
içinde olmalıdır. Sekme çubukları ve diğer gezinme öğeleri de uygulamanın geri kalanından ayrılmalıdır. Büyük listelerin genellikle kendi FocusArea
'leri olmalıdır. Aksi takdirde, kullanıcıların bazı görünümlere erişmek için listenin tamamını döndürmesi gerekir.
FocusArea
, car-ui-library'deki LinearLayout
sınıfının alt sınıfıdır.
Bu özellik etkinleştirildiğinde FocusArea
, alt öğelerinden biri odaklandığında vurgu çizer. Daha fazla bilgi için Odak vurgusu özelleştirme başlıklı makaleyi inceleyin.
Sayfa düzeni dosyasında bir gezinme bloğu oluştururken bu blok için kapsayıcı olarak LinearLayout
kullanmak istiyorsanız bunun yerine FocusArea
kullanın.
Aksi takdirde, bloğu bir FocusArea
içine sarın.
Bir FocusArea
öğesini başka bir FocusArea
öğesinin içine YERLEŞTİRMEYİN.
Aksi takdirde, beklenmeyen sonuçlar ortaya çıkacaktır. Tüm odaklanılabilir görünümlerin bir FocusArea
içine yerleştirildiğinden emin olun.
Aşağıda, RotaryPlayground
içinde FocusArea
örneği gösterilmektedir:
<com.android.car.ui.FocusArea android:layout_margin="16dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true"> </EditText> </com.android.car.ui.FocusArea>
FocusArea
şu şekilde çalışır:
RotaryService
, döndürme ve itme işlemlerini işlerken görünüm hiyerarşisindeFocusArea
örneklerini arar.RotaryService
, döndürme etkinliği aldığında odak noktasını aynıFocusArea
içinde odak alabilecek başka bir Görünüm'e taşır.- Bir hatırlatma etkinliği aldığında
RotaryService
, odağın başka bir (genellikle bitişik)FocusArea
'te alınabileceği başka bir görünüme taşınmasını sağlar.
Düzeninize FocusAreas
eklemezseniz kök görünüm, gizli bir odak alanı olarak değerlendirilir. Kullanıcı, uygulamada gezinmek için ekranı kaydıramaz. Bunun yerine, tüm odaklanılabilir görünümler arasında geçiş yapar. Bu, iletişim kutuları için yeterli olabilir.
FocusArea özelleştirmesi
Döner gezinmeyi özelleştirmek için iki standart görüntüleme özelliği kullanılabilir:
android:nextFocusForward
, uygulama geliştiricilerin bir odak alanındaki dönme sırasını belirtmesine olanak tanır. Bu, klavye gezinme için Sekme sırasını kontrol etmek için kullanılan aynı özelliktir. Döngü oluşturmak için bu özelliği KULLANMAYIN. Bunun yerine, döngü oluşturmak içinapp:wrapAround
simgesini (aşağıya bakın) kullanın.android:focusedByDefault
, uygulama geliştiricilerin pencerede varsayılan odak görünümünü belirtmesine olanak tanır. Bu özelliği veapp:defaultFocus
özelliğini (aşağıya bakın) aynıFocusArea
içinde KULLANMAYIN.
FocusArea
, döner gezinmeyi özelleştirmek için bazı özellikleri de tanımlar.
Örtük odak alanları bu özelliklerle özelleştirilemez.
- (Android 11 QPR3, Android 11 Car,
Android 12)
app:defaultFocus
, kullanıcı buFocusArea
'e dokunduğunda odaklanılması gereken, odaklanılabilir bir alt öğe görünümünün kimliğini belirtmek için kullanılabilir. - (Android 11 QPR3, Android 11 Car,
Android 12)
app:defaultFocusOverridesHistory
geçmişi ile birlikte, buFocusArea
içinde başka bir görünüme odaklanmış olsa bile yukarıda belirtilen görünümün odağa alınması içintrue
olarak ayarlanabilir. - (Android 12)
Odaklanabilir bir alt öğe görünümünün kimliğini belirtmek içinapp:nudgeLeftShortcut
,app:nudgeRightShortcut
,app:nudgeUpShortcut
veapp:nudgeDownShortcut
öğelerini kullanın. Bu görünüm, kullanıcı belirli bir yönde hareket ettiğinde odaklanmalıdır. Daha fazla bilgi edinmek için aşağıdaki İpucu kısayolları bölümünü inceleyin.(Android 11 QPR3, Android 11 Car, Android 12'de desteği sonlandırıldı)
app:nudgeShortcut
veapp:nudgeShortcutDirection
yalnızca bir dürtme kısayolunu destekler. - (Android 11 QPR3, Android 11 Car,
Android 12)
BuFocusArea
içinde dönmenin sarmalanması içinapp:wrapAround
true
olarak ayarlanabilir. Bu yöntem genellikle görünümler daire veya oval şeklinde düzenlendiğinde kullanılır. - (Android 11 QPR3, Android 11 Car,
Android 12)
BuFocusArea
'teki öne çıkan anların kenarlık kalınlığını ayarlamak içinapp:highlightPaddingStart
,app:highlightPaddingEnd
,app:highlightPaddingTop
,app:highlightPaddingBottom
,app:highlightPaddingHorizontal
veapp:highlightPaddingVertical
simgesini kullanın. - (Android 11 QPR3, Android 11 Car,
Android 12)
Bir dürtme hedefi bulmak için buFocusArea
öğesinin algılanan sınırlarını ayarlamak istersenizapp:startBoundOffset
,app:endBoundOffset
,app:topBoundOffset
,app:bottomBoundOffset
,app:horizontalBoundOffset
veapp:verticalBoundOffset
öğelerini kullanın. - (Android 11 QPR3, Android 11 Car,
Android 12)
Belirtilen yönlerde bitişik birFocusArea
'ın (veya alanların) kimliğini açıkça belirtmek içinapp:nudgeLeft
,app:nudgeRight
,app:nudgeUp
veapp:nudgeDown
öğelerini kullanın. Varsayılan olarak kullanılan geometrik arama istenen hedefi bulamadığı durumlarda bunu kullanın.
Uyarıcı genellikle odak alanları arasında gezinir. Ancak dürtme kısayollarında, dürtme bazen önce bir FocusArea
içinde gezinir. Bu nedenle, kullanıcının bir sonraki FocusArea
'ye gitmek için iki kez dürtmesi gerekebilir. FocusArea
öğesinde uzun bir listenin ardından Yüzen İşlem Düğmesi bulunduğunda (aşağıdaki örnekte gösterildiği gibi) hatırlatma kısayolları kullanışlıdır:

Uyarıcı kısayolu olmadan kullanıcının FAB'a ulaşmak için listenin tamamını döndürmesi gerekir.
Odak vurgusu özelleştirmesi
Yukarıda belirtildiği gibi RotaryService
, Android çerçevesinin mevcut görüntü odak kavramına dayanır. Kullanıcı döndürüp ittiğinde RotaryService
, odak noktasını hareket ettirerek bir görünüme odaklanır ve diğer görünümün odağını kaldırır. Android'de, bir görünüme odaklanıldığında görünüm:
- Kendi odak vurgusunu belirtmişse Android, görünümün odak vurgusunu çizer.
- Bir odak vurgusu belirtilmezse ve varsayılan odak vurgusu devre dışı bırakılmazsa Android, görünüm için varsayılan odak vurgusunu çizer.
Dokunma için tasarlanmış uygulamalar genellikle uygun odak vurgularını belirtmez.
Varsayılan odak vurgusu Android çerçevesi tarafından sağlanır ve OEM tarafından geçersiz kılınabilir. Uygulama geliştiriciler, kullandıkları tema Theme.DeviceDefault
'ten türetildiğinde bu izni alır.
Tutarlı bir kullanıcı deneyimi için mümkün olduğunda varsayılan odak vurgusunu kullanın.
Özel şekilli (ör. yuvarlak veya hap şeklinde) bir odak vurgusuna ihtiyacınız varsa ya da Theme.DeviceDefault
'ten türetilmemiş bir tema kullanıyorsanız her görünüm için kendi odak vurgunuzu belirtmek üzere car-ui-library kaynaklarını kullanın.
Bir görünüm için özel bir odak vurgusu belirtmek istiyorsanız görünümün arka plan veya ön plan çizilebilir öğesini, görünüme odaklanıldığında farklı olan bir çizilebilir öğeyle değiştirin. Genellikle arka planı değiştirirsiniz. Aşağıdaki çizilebilir öğe, kare görünümün arka planı olarak kullanıldığında yuvarlak bir odak vurgusu oluşturur:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:state_pressed="true"> <shape android:shape="oval"> <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/> <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width" android:color="@color/car_ui_rotary_focus_pressed_stroke_color"/> </shape> </item> <item android:state_focused="true"> <shape android:shape="oval"> <solid android:color="@color/car_ui_rotary_focus_fill_color"/> <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width" android:color="@color/car_ui_rotary_focus_stroke_color"/> </shape> </item> <item> <ripple...> ... </ripple> </item> </selector>
(Android 11 QPR3, Android 11 Car, Android 12) Yukarıdaki örnekteki kalın kaynak referansları, car-ui-library tarafından tanımlanan kaynakları tanımlar. OEM, belirttiği varsayılan odak vurgusuyla tutarlı olması için bunları geçersiz kılar. Bu sayede, kullanıcı özel odak vurgusu içeren bir görünüm ile varsayılan odak vurgusu içeren bir görünüm arasında gezinirken odak vurgusu rengi, çizgi genişliği vb. değişmez. Son öğe, dokunma için kullanılan bir dalgadır. Kalın kaynaklar için kullanılan varsayılan değerler aşağıdaki gibi görünür:

Ayrıca, aşağıdaki örnekte gösterildiği gibi bir düğmeye kullanıcının dikkatini çekmek için düz bir arka plan rengi verildiğinde özel bir odak vurgusu çağrılır. Bu durum, odak vurgusunun görülmesini zorlaştırabilir. Bu durumda, ikincil renkleri kullanarak özel bir odak vurgusu belirtin:
![]() |
- (Android 11 QPR3, Android 11 Car,
Android 12)
car_ui_rotary_focus_fill_secondary_color
car_ui_rotary_focus_stroke_secondary_color
- (Android 12)
car_ui_rotary_focus_pressed_fill_secondary_color
car_ui_rotary_focus_pressed_stroke_secondary_color
Örnek:
![]() |
![]() |
|
Basılmamış, odaklanmış | Odaklanmış, basılı |
Döner kaydırma
Uygulamanız RecyclerView
kullanıyorsa bunun yerine CarUiRecyclerView
kullanmalısınız. OEM'lerin özelleştirmeleri tüm CarUiRecyclerView
'ler için geçerli olduğundan bu, kullanıcı arayüzünüzün diğerleriyle tutarlı olmasını sağlar.
Listenizdeki tüm öğeler odaklanılabilir durumdaysa başka bir işlem yapmanız gerekmez. Döner gezinme, odağı listedeki öğeler arasında taşır ve yeni odaklanan öğeyi görünür kılmak için liste kaydırılır.
(Android 11 QPR3, Android 11 Car,
Android 12)
Odaklanabilir ve odaklanamayan öğelerin bir karışımı varsa veya tüm öğeler odaklanamıyorsa kullanıcının, odaklanamayan öğeleri atlamadan listede kademeli olarak kaydırması için döner kaydırma özelliğini etkinleştirebilirsiniz. Dönen kaydırma özelliğini etkinleştirmek için app:rotaryScrollEnabled
özelliğini true
olarak ayarlayın.
(Android 11 QPR3, Android 11 Car,
Android 12)
CarUiUtils
'teki setRotaryScrollEnabled()
yöntemini kullanarak avCarUiRecyclerView
dahil olmak üzere tüm kaydırılabilir görünümlerde dönen kaydırma özelliğini etkinleştirebilirsiniz. Bu durumda şunları yapmanız gerekir:
- Kaydırılabilir görünümü, odaklanılabilir alt görünümlerinin hiçbiri görünür olmadığında odaklanabilmesi için odaklanılabilir hale getirin.
- Kaydırılabilir görünümün odaklanmış görünmemesi için
setDefaultFocusHighlightEnabled(false)
çağrısı yaparak kaydırılabilir görünümdeki varsayılan odak vurgulamayı devre dışı bırakın. setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
çağrısı yaparak kaydırılabilir görünümün, alt öğelerinden önce odaklandığından emin olun.- Kaydırma mesafesini ve yönünü (işaret aracılığıyla) belirtmek için
SOURCE_ROTARY_ENCODER
ile birlikte MotionEvents'i veAXIS_VSCROLL
veyaAXIS_HSCROLL
öğesini dinleyin.
Bir CarUiRecyclerView
'te döner kaydırma etkinleştirildiğinde ve kullanıcı, odaklanılabilir görünümlerin bulunmadığı bir alana döndürdüğünde kaydırma çubuğunun odaklanıldığını belirtmek için rengi griden maviye döner. İsterseniz benzer bir efekt uygulayabilirsiniz.
MotionEvents, kaynak dışında faredeki kaydırma tekerleği tarafından oluşturulanlarla aynıdır.
Doğrudan işleme modu
Normalde, dokunma ve döndürme işlemleri kullanıcı arayüzünde gezinirken orta düğmeye basmak işlem yapar. Ancak bu durum her zaman geçerli değildir. Örneğin, bir kullanıcı alarm sesini ayarlamak isterse ses kaydırma çubuğunu açmak için döner kontrol cihazını kullanabilir, orta düğmeye basabilir, alarm sesini ayarlamak için kontrol cihazını döndürebilir ve ardından geri düğmesine basarak gezinmeye geri dönebilir. Buna doğrudan değiştirme (DM) modu denir. Bu modda, döner kontrol cihazı gezinmek yerine doğrudan görünümle etkileşimde bulunmak için kullanılır.
DM'yi iki şekilde uygulayabilirsiniz. Yalnızca döndürmeyi ele almanız gerekiyorsa ve değiştirmek istediğiniz görünüm ACTION_SCROLL_FORWARD
ve ACTION_SCROLL_BACKWARD
AccessibilityEvent
'lere uygun şekilde yanıt veriyorsa basit mekanizmayı kullanın. Aksi takdirde gelişmiş mekanizmayı kullanın.
Basit mekanizma, sistem pencerelerinde tek seçenektir; uygulamalar her iki mekanizmayı da kullanabilir.
Basit mekanizma
(Android 11 QPR3, Android 11 Car,
Android 12)
Uygulamanız DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable)
çağrısını yapmalıdır.
RotaryService
, kullanıcının DM modunda olduğunu algılar ve bir görünüm odaklanırken kullanıcı Merkez düğmesine bastığında DM moduna girer. DM modundayken ACTION_SCROLL_FORWARD
veya ACTION_SCROLL_BACKWARD
döndürme işlemleri yapılır ve kullanıcı Geri düğmesine bastığında DM modundan çıkılır. Basit mekanizma, DM moduna girip çıkarken görünümün seçili durumunu değiştirir.
Kullanıcının DM modunda olduğunu görsel olarak belirtmek için görünümünüzü, seçildiğinde farklı görünecek şekilde ayarlayın. Örneğin, android:state_selected
true
olduğunda arka planı değiştirin.
Gelişmiş mekanizma
Uygulama, RotaryService
'ün DM moduna ne zaman girip çıkacağını belirler. Tutarlı bir kullanıcı deneyimi için DM görünümü odaklıyken Orta düğmesine basıldığında DM moduna, Geri düğmesine basıldığında ise DM modundan çıkılmalıdır. Ortaya getirme düğmesi ve/veya hatırlatma kullanılmıyorsa DM modundan çıkmanın alternatif yolları olabilir. Haritalar gibi uygulamalarda DM moduna girmek için DM'yi temsil eden bir düğme kullanılabilir.
Gelişmiş DM modunu desteklemek için bir görünüm:
- (Android 11 QPR3, Android 11 Car,
Android 12) DM moduna girmek için
KEYCODE_DPAD_CENTER
ve DM modundan çıkmak içinKEYCODE_BACK
etkinliğini dinlemeli ve her iki durumda daDirectManipulationHelper.enableDirectManipulationMode()
işlevini çağırmalıdır. Bu etkinlikleri dinlemek için aşağıdakilerden birini yapın:OnKeyListener
kaydedin.
veya
- Görünümü genişletin ve ardından
dispatchKeyEvent()
yöntemini geçersiz kılın.
- Görüntü, otomatik hatırlatmaları yönetmesi gerekiyorsa otomatik hatırlatma etkinliklerini (
KEYCODE_DPAD_UP
,KEYCODE_DPAD_DOWN
,KEYCODE_DPAD_LEFT
veyaKEYCODE_DPAD_RIGHT
) dinlemelidir. - Görüntüleme rotasyonu yönetmek istiyorsa
MotionEvent
'leri dinlemeli veAXIS_SCROLL
'te rotasyon sayısını almalıdır. Bunu yapmanın birkaç yolu vardır:OnGenericMotionListener
kaydedin.- Görünümü genişletin ve
dispatchTouchEvent()
yöntemini geçersiz kılın.
- DM modunda takılmamak için, görüntülemenin ait olduğu Fragment veya Etkinlik etkileşimli olmadığında DM modundan ÇIKMALIDIR.
- Görünümün DM modunda olduğunu belirten görsel bir ipucu SAĞLANMALIDIR.
Haritayı kaydırıp yakınlaştırmak için DM modunu kullanan özel bir görünüm örneği aşağıda verilmiştir:
/** Whether this view is in DM mode. */ private boolean mInDirectManipulationMode;
/** Initializes the view. Called by the constructors. */ private void init() { setOnKeyListener((view, keyCode, keyEvent) -> { boolean isActionUp = keyEvent.getAction() == KeyEvent.ACTION_UP; switch (keyCode) { // Always consume KEYCODE_DPAD_CENTER and KEYCODE_BACK events. case KeyEvent.KEYCODE_DPAD_CENTER: if (!mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = true; DirectManipulationHelper.enableDirectManipulationMode(this, true); setSelected(true); // visually indicate DM mode } return true; case KeyEvent.KEYCODE_BACK: if (mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); setSelected(false); } return true; // Consume controller nudge events only when in DM mode. // When in DM mode, nudges pan the map. case KeyEvent.KEYCODE_DPAD_UP: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, -10f); return true; case KeyEvent.KEYCODE_DPAD_DOWN: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, 10f); return true; case KeyEvent.KEYCODE_DPAD_LEFT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(-10f, 0f); return true; case KeyEvent.KEYCODE_DPAD_RIGHT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(10f, 0f); return true; // Don't consume other key events. default: return false; } });
// When in DM mode, rotation zooms the map. setOnGenericMotionListener(((view, motionEvent) -> { if (!mInDirectManipulationMode) return false; float scroll = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL); zoom(10 * scroll); return true; })); }
@Override public void onPause() { if (mInDirectManipulationMode) { // To ensure that the user doesn't get stuck in DM mode, disable DM mode // when the fragment is not interactive (e.g., a dialog shows up). mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); } super.onPause(); }
Daha fazla örneği RotaryPlayground
projesinde bulabilirsiniz.
ActivityView
ActivityView kullanılırken:
ActivityView
odaklanılabilir olmamalıdır.- (Android 11 QPR3, Android 11 Car,
Android 11'de desteği sonlandırıldı)
ActivityView
içeriği, ilk odaklanılabilir görünüm olarak birFocusParkingView
içermeli veapp:shouldRestoreFocus
özelliğifalse
olmalıdır. ActivityView
içeriğininandroid:focusByDefault
görüntülemesi olmamalıdır.
Kullanıcı için etkinlik görünümlerinin gezinme üzerinde hiçbir etkisi olmamalıdır. Bunun tek istisnası, odak alanlarının etkinlik görünümlerini kapsayamamasıdır. Diğer bir deyişle, ActivityView
içinde ve dışında içerik barındıran tek bir odak alanı olamaz. ActivityView
öğenize FocusAreas eklemezseniz ActivityView
'teki görünüm hiyerarşisinin kökü, gizli bir odak alanı olarak kabul edilir.
Basılı tutulurken çalışan düğmeler
Çoğu düğme tıklandığında bir işlem yapar. Bazı düğmeler ise basılı tutularak çalışır.
Örneğin, ileri sarma ve geri sarma düğmeleri genellikle basılı tutularak çalışır. Bu tür düğmelerin döner düğmeyi desteklemesi için aşağıdaki gibi KEYCODE_DPAD_CENTER
KeyEvents
değerini dinleyin:
mButton.setOnKeyListener((v, keyCode, event) -> { if (keyCode != KEYCODE_DPAD_CENTER) { return false; } if (event.getAction() == ACTION_DOWN) { mButton.setPressed(true); mHandler.post(mRunnable); } else { mButton.setPressed(false); mHandler.removeCallbacks(mRunnable); } return true; });
Bu durumda mRunnable
bir işlem yapar (ör. geri sarma) ve kendisini bir gecikme sonrasında çalıştırılacak şekilde planlar.
Dokunma modu
Kullanıcılar, bir araçtaki ana üniteyle etkileşimde bulunmak için döner kontrol cihazını kullanarak veya ekrana dokunarak iki şekilde döner kontrol cihazı kullanabilir. Döner kontrol cihazı kullanıldığında, odaklanılabilir görünümlerden biri vurgulanır. Ekrana dokunduğunuzda odak vurgusu görünmez. Kullanıcı dilediğinde aşağıdaki giriş modları arasında geçiş yapabilir:
- Döner düğme → dokunma. Kullanıcı ekrana dokunduğunda odaklanma vurgusu kaybolur.
- Dokun → döner. Kullanıcı ekranı hareket ettirdiğinde, döndürdüğünde veya Ortala düğmesine bastığında odaklanma vurgusu görünür.
Geri ve Ana Sayfa düğmelerinin giriş modu üzerinde herhangi bir etkisi yoktur.
Döner kontrol paneli, Android'in mevcut dokunma modu konseptini kullanır.
Kullanıcının hangi giriş modunu kullandığını belirlemek için View.isInTouchMode()
parametresini kullanabilirsiniz. Değişiklikleri dinlemek için OnTouchModeChangeListener
simgesini kullanabilirsiniz. Bu seçenek, kullanıcı arayüzünüzü mevcut giriş moduna göre özelleştirmek için kullanılabilir. Ancak endişe verici olabileceğinden büyük değişikliklerden kaçının.
Sorun giderme
Dokunma için tasarlanmış bir uygulamada, iç içe yerleştirilmiş odaklanılabilir görünümler olması yaygındır.
Örneğin, bir ImageButton
etrafında odaklanılabilir bir FrameLayout
olabilir. Bu, dokunmatik ekran için sorun oluşturmaz ancak kullanıcının bir sonraki etkileşimli görünüme geçmek için kontrol cihazını iki kez döndürmesi gerektiğinden, döner kontrol cihazı için kötü bir kullanıcı deneyimine neden olabilir. Google, iyi bir kullanıcı deneyimi için dış görünümü veya iç görünümü odaklanılabilir hale getirmenizi önerir. İkisini birden odaklanılabilir hale getirmemenizi öneririz.
Döner kontrol düğmesi kullanılarak basılan bir düğme veya anahtar odağını kaybederse aşağıdaki koşullardan biri geçerli olabilir:
- Düğmeye basıldığı için düğme veya anahtar devre dışı bırakılıyor (kısa süreliğine veya süresiz olarak). Her iki durumda da bu sorunu gidermenin iki yolu vardır:
android:enabled
durumunutrue
olarak bırakın ve düğmeyi veya anahtarı devre dışı bırakmak için Özel Durum bölümünde açıklandığı şekilde özel bir durum kullanın.- Düğmeyi veya anahtarı çevrelemek için bir kapsayıcı kullanın ve düğme veya anahtar yerine kapsayıcıyı odaklanılabilir hale getirin. (Tıklama dinleyicisi kapsayıcıda olmalıdır.)
- Düğme veya anahtar değiştiriliyor. Örneğin, düğmeye basıldığında veya anahtar değiştirildiğinde yapılan işlem, mevcut düğmelerin yeni düğmelerle değiştirilmesine neden olacak şekilde mevcut işlemlerin yenilenmesini tetikleyebilir. Bu sorunu gidermenin iki yolu vardır:
- Yeni bir düğme veya anahtar oluşturmak yerine, mevcut düğmenin veya anahtarın simgesini ve/veya metnini ayarlayın.
- Yukarıda olduğu gibi, düğmenin veya anahtarın etrafına odaklanılabilir bir kapsayıcı ekleyin.
RotaryPlayground
RotaryPlayground
, döner reklamlar için bir referans uygulamasıdır. Döner özellikleri uygulamalarınıza nasıl entegre edeceğinizi öğrenmek için bu kılavuzu kullanın. RotaryPlayground
, emülatör derlemelerine ve Android Automotive OS (AAOS) çalıştıran cihazların derlemelerine dahildir.
RotaryPlayground
deposu:packages/apps/Car/tests/RotaryPlayground/
- Sürümler: Android 11 QPR3, Android 11 Car ve Android 12
RotaryPlayground
uygulamasının sol tarafında aşağıdaki sekmeler gösterilir:
- Kartlar. Odaklanabilir alanlar arasında gezinmeyi, odaklanamayan öğeleri ve metin girişini atlayarak test edin.
- Doğrudan Manipülasyon. Basit ve gelişmiş doğrudan işlem modunu destekleyen widget'ları test edin. Bu sekme, özellikle uygulama penceresinde doğrudan değişiklik yapmak içindir.
- Sys UI Manipulation. Yalnızca basit doğrudan işleme modunun desteklendiği sistem pencerelerinde doğrudan işleme özelliğini destekleyen widget'ları test edin.
- Izgara Kaydırmayla z-şeklinde dönen gezinmeyi test edin.
- Bildirim. Uyarıları gösterme ve gizleme özelliğini test edin.
- Kaydırın. Odaklanabilir ve odaklanamayan içeriklerin bir arada bulunduğu sayfalarda kaydırma işlemini test edin.
- WebView.
WebView
içindeki bağlantılar arasında gezinmeyi test edin. - Özel
FocusArea
.FocusArea
özelleştirmesini test edin:- Etrafından dolaşarak şut.
android:focusedByDefault
veapp:defaultFocus
.
- Belirli bir işleme yönlendirme hedefleri.
- Uyarıcı kısayollar.
- Odaklanabilir görünümü olmayan
FocusArea
.