Aşağıdaki materyal uygulama geliştiricileri içindir.
Uygulama desteğinizi döner hale getirmek için şunları yapmanız GEREKİR:
- İlgili etkinlik düzenine bir
FocusParkingView
yerleştirin. - Odaklanabilen (veya odaklanamayan) görünümlerden emin olun.
-
FocusParkingView
dışındaki tüm odaklanılabilir görünümlerinizi sarmak içinFocusArea
s'yi kullanın.
Ortamınızı rotary özellikli uygulamalar geliştirecek şekilde ayarladıktan sonra, bu görevlerin her biri aşağıda ayrıntılı olarak açıklanmaktadır.
Döner denetleyiciyi ayarlama
Döner özellikli uygulamalar geliştirmeye başlamadan önce bir döner denetleyiciye veya bir yedek parçaya ihtiyacınız vardır. Aşağıda açıklanan seçeneklere sahipsiniz.
Emülatör
source build/envsetup.sh && lunch car_x86_64-userdebug m -j emulator -wipe-data -no-snapshot -writable-system
Ayrıca aosp_car_x86_64-userdebug
kullanabilirsiniz.
Benzetilmiş döner denetleyiciye erişmek için:
- Araç çubuğunun altındaki üç noktaya dokunun:
- Genişletilmiş kontroller penceresinde Araba döner seçeneğini seçin:
USB klavye
- Android Automotive OS (AAOS) çalıştıran cihazınıza bir USB klavye takın. Bu, bazı durumlarda ekran klavyesinin görünmesini engeller.
- Bir
userdebug
veyaeng
yapısı kullanın. - Anahtar olay filtrelemeyi etkinleştirin:
adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
- Her eyleme karşılık gelen anahtarı bulmak için aşağıdaki tabloya bakın:
Anahtar Döner eylem Q Saat yönünün tersine çevirin e Saat yönünde döndür A Sola sürükle D Sağa sürükle K Yukarı it S Aşağı it F veya Virgül Orta düğme R veya Esc Geri butonu
ADB komutları
Döner giriş olaylarını enjekte etmek 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ı | Döner giriş |
---|---|
adb shell cmd car_service inject-rotary | Saat yönünün tersine çevirin |
adb shell cmd car_service inject-rotary -c true | Saat yönünde döndür |
adb shell cmd car_service inject-rotary -dt 100 50 | Birden çok kez saat yönünün tersine döndür (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ı it |
adb shell cmd car_service inject-key 281 | Aşağı it |
adb shell cmd car_service inject-key 23 | Ortadaki düğmeye tıklama |
adb shell input keyevent inject-key 4 | Geri düğmesine tıklayın |
OEM döner denetleyici
Döner kontrol cihazı donanımınız çalışır durumda olduğunda bu en gerçekçi seçenektir. Özellikle hızlı dönüşü test etmek için kullanışlıdır.
OdaklanmaPark Görünümü
FocusParkingView
Araç Kullanıcı Arayüzü Kitaplığı'ndaki (araba-ui-kütüphanesi) şeffaf bir görünümdür. RotaryService
bunu döner kontrol cihazı navigasyonunu desteklemek için kullanır. FocusParkingView
düzendeki ilk odaklanılabilir görünüm olmalıdır. Tüm FocusArea
dışına yerleştirilmelidir. Her pencerede bir FocusParkingView
bulunmalıdır. Zaten FocusParkingView
içeren car-ui-library temel düzenini kullanıyorsanız başka bir FocusParkingView
eklemenize gerek yoktur. Aşağıda RotaryPlayground
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
ihtiyaç duymanızın nedenleri şunlardır:
- Odak başka bir pencerede ayarlandığında Android odağı otomatik olarak temizlemez. Önceki penceredeki odağı temizlemeye çalışırsanız Android, o penceredeki bir görünüme yeniden odaklanır ve bu da iki pencerenin aynı anda odaklanmasına neden olur. Her pencereye
FocusParkingView
eklemek bu sorunu çözebilir. Bu görünüm şeffaftır ve varsayılan odak vurgusu devre dışıdır, böylece odaklanmış olsun ya da olmasın kullanıcı tarafından görülmez. Odaklamayı alabilir, böyleceRotaryService
odak vurgusunu kaldırmak için odağı onun üzerine park edebilir. - Geçerli pencerede yalnızca bir
FocusArea
varsa, kontrol ünitesininFocusArea
döndürülmesi,RotaryService
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, odağı hareket ettirmeyerek sarmalamayı önlediği noktada bir sarmanın meydana gelmek üzere olduğunu belirleyebilir. - 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 odağı uygular.
Odaklanabilir görünümler
RotaryService
telefonların fiziksel klavyeleri ve D-pad'leri olduğu zamanlara dayanan, Android çerçevesinin mevcut görüntüleme odağı konseptini temel alır. Mevcut android:nextFocusForward
özelliği, döner kullanım için yeniden tasarlandı (bkz. FocusArea özelleştirmesi ), ancak android:nextFocusLeft
, android:nextFocusRight
, android:nextFocusUp
ve android:nextFocusDown
böyle değildir.
RotaryService
yalnızca odaklanılabilir görüşlere odaklanır. Button
gibi bazı görünümler genellikle odaklanabilir. TextView
ve ViewGroup
gibi diğerleri genellikle değildir. Tıklanabilir görünümler otomatik olarak odaklanabilir ve görünümler, bir tıklama dinleyicisine sahip olduklarında otomatik olarak tıklanabilir. Bu otomatik mantık istenen odaklanılabilirlikle sonuçlanırsa görünümün odaklanabilirliğini açıkça ayarlamanız gerekmez. Otomatik mantık istenen odaklanılabilirliği sağlayamazsa, android:focusable
niteliğini true
veya false
olarak ayarlayın veya görünümün odaklanabilirliğini View.setFocusable(boolean)
ile programlı olarak ayarlayın. RotaryService
buna odaklanabilmesi için, bir görünümün aşağıdaki gereksinimleri karşılaması ZORUNLUDUR:
- Odaklanabilir
- Etkinleştirilmiş
- Görünür
- Genişlik ve yükseklik için sıfır olmayan değerlere sahip olun
Bir görünüm, örneğin odaklanabilir ancak devre dışı bırakılmış bir düğme gibi tüm bu gereksinimleri karşılamıyorsa, kullanıcı ona odaklanmak için döner kontrolü kullanamaz. Devre dışı bırakılan görünümlere odaklanmak istiyorsanız, görünümün nasıl göründüğünü, Android'in devre dışı olarak kabul etmesi gerektiğini belirtmeden kontrol etmek için android:state_enabled
yerine özel bir durum kullanmayı düşünün. Uygulamanız, dokunulduğunda görünümün neden devre dışı bırakıldığını kullanıcıya bildirebilir. Bir sonraki bölümde bunun nasıl yapılacağı açıklanmaktadır.
Özel durum
Özel bir durum eklemek için:
- Görünümünüze özel bir özellik eklemek için. Örneğin,
CustomView
görünüm sınıfınastate_rotary_enabled
özel durumu eklemek için şunu kullanın:<declare-styleable name="CustomView"> <attr name="state_rotary_enabled" format="boolean" /> </declare-styleable>
- Bu durumu izlemek için görünümünüze erişimci yöntemleriyle birlikte bir örnek değişkeni ekleyin:
private boolean mRotaryEnabled; public boolean getRotaryEnabled() { return mRotaryEnabled; } public void setRotaryEnabled(boolean rotaryEnabled) { mRotaryEnabled = rotaryEnabled; }
- Görünümü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ünüm sınıfınızda
onCreateDrawableState()
yöntemini geçersiz kılın ve ardından uygun olduğunda özel durumu ekleyin. Örneğin:@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ı performans göstermesini sağlayın. Örneğin, tıklama işleyicisi hiçbir şey yapmayabilir veya
mRotaryEnabled
false
olduğunda bir uyarı görüntüleyebilir. - Düğmenin devre dışı görünmesini sağlamak için görünümünüzün arka planında çizilebilir,
android:state_enabled
yerineapp:state_rotary_enabled
kullanın. Henüz sahip değilseniz şunu eklemeniz gerekir:xmlns:app="http://schemas.android.com/apk/res-auto"
- Görünümünüz herhangi bir düzende devre dışı bırakıldıysa,
android:enabled="false"
app:state_rotary_enabled="false"
ile değiştirin ve ardından yukarıdaki gibiapp
ad alanını ekleyin. - Görünümünüz program aracılığıyla devre dışı bırakıldıysa,
setEnabled()
çağrılarınısetRotaryEnabled()
çağrılarıyla değiştirin.
Odak Alanı
Gezinmeyi kolaylaştırmak ve diğer uygulamalarla tutarlı olmak amacıyla odaklanabilir görünümleri bloklara bölmek için FocusAreas
kullanın. Örneğin, uygulamanızda bir araç çubuğu varsa araç çubuğu, uygulamanızın geri kalanından ayrı bir FocusArea
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
olmalıdır. Değilse, kullanıcıların bazı görünümlere erişmek için listenin tamamını döndürmeleri gerekir.
FocusArea
, araç kullanıcı arayüzü kitaplığında LinearLayout
bir alt sınıfıdır. Bu özellik etkinleştirildiğinde FocusArea
, alt öğelerinden birine odaklanıldığında bir vurgu çizer. Daha fazla bilgi edinmek için bkz. Odak vurgusunu özelleştirme .
Düzen dosyasında bir gezinme bloğu oluştururken, bu blok için kapsayıcı olarak bir LinearLayout
kullanmayı düşünüyorsanız bunun yerine FocusArea
kullanın. Aksi takdirde bloğu FocusArea
sarın.
Bir FocusArea
başka bir FocusArea
YERLEŞTİRMEYİN . Bunu yapmak tanımsız gezinme davranışına yol açar. Tüm odaklanılabilir görünümlerin bir FocusArea
içinde yuvalandığından emin olun.
RotaryPlayground
bir FocusArea
örneği aşağıda 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:
- Döndürme ve itme eylemlerini gerçekleştirirken,
RotaryService
görünüm hiyerarşisindeFocusArea
örneklerini arar. - Bir rotasyon olayı alındığında,
RotaryService
odağı aynıFocusArea
alabilecek başka bir Görünüme taşır. - Bir dürtme olayı alındığında,
RotaryService
odağı başka bir (genellikle bitişik)FocusArea
alabilecek başka bir görünüme taşır.
Mizanpajınıza herhangi bir FocusAreas
eklemezseniz kök görünüm, örtülü bir odak alanı olarak değerlendirilir. Kullanıcı uygulamada gezinmek için dürtülemez. Bunun yerine, diyaloglar için yeterli olabilecek tüm odaklanılabilir görünümler arasında geçiş yapacaklardır.
Odak Alanı özelleştirmesi
Döner gezinmeyi özelleştirmek için iki standart Görünüm özelliği kullanılabilir:
-
android:nextFocusForward
uygulama geliştiricilerinin bir odak alanındaki dönüş sırasını belirlemesine olanak tanır. Bu, klavyede gezinme için Sekme sırasını kontrol etmek için kullanılan özniteliğin aynısıdır. Bir döngü oluşturmak için bu özelliği KULLANMAYIN . Bunun yerine, bir döngü oluşturmak içinapp:wrapAround
(aşağıya bakın) kullanın. -
android:focusedByDefault
uygulama geliştiricilerinin penceredeki varsayılan odak görünümünü belirlemesine olanak tanır. Bu özelliği veapp:defaultFocus
(aşağıya bakın) aynıFocusArea
içinde KULLANMAYIN .
FocusArea
ayrıca döner gezinmeyi özelleştirmek için bazı nitelikleri de tanımlar. Örtülü odak alanları bu niteliklerle özelleştirilemez.
- ( Android 11 QPR3, Android 11 Araba, Android 12 )
app:defaultFocus
odaklanılabilir bir alt görünümün kimliğini belirtmek için kullanılabilir; kullanıcı buFocusArea
öğesine dokunduğunda odaklanılması gerekir. - ( Android 11 QPR3, Android 11 Araba, Android 12 )
app:defaultFocusOverridesHistory
buFocusArea
başka bir görünüme odaklanıldığını belirtmek için geçmişle birlikte yukarıda belirtilen görünümün odaklanmasını sağlamak içintrue
olarak ayarlanabilir. - ( Android 12 )
Kullanıcı belirli bir yönde dürtüklendiğinde odaklanılması gereken odaklanılabilir alt görünümün kimliğini belirtmek içinapp:nudgeLeftShortcut
,app:nudgeRightShortcut
,app:nudgeUpShortcut
veapp:nudgeDownShortcut
öğelerini kullanın. Daha fazla bilgi edinmek için aşağıdaki dürtme kısayollarına ilişkin içeriğe bakın.( Android 11 QPR3, Android 11 Car, Android 12'de kullanımdan kaldırıldı )
app:nudgeShortcut
veapp:nudgeShortcutDirection
yalnızca bir dürtme kısayolunu destekledi. - ( Android 11 QPR3, Android 11 Araba, Android 12 )
BuFocusArea
döndürmenin sarılmasını sağlamak içinapp:wrapAround
true
olarak ayarlanabilir. Bu genellikle görünümler daire veya oval şeklinde düzenlendiğinde kullanılır. - ( Android 11 QPR3, Android 11 Araba, Android 12 )
BuFocusArea
vurgunun dolgusunu ayarlamak içinapp:highlightPaddingStart
,app:highlightPaddingEnd
,app:highlightPaddingTop
,app:highlightPaddingBottom
,app:highlightPaddingHorizontal
veapp:highlightPaddingVertical
kullanın. - ( Android 11 QPR3, Android 11 Araba, Android 12 )
Bir itme hedefi bulmak amacıyla buFocusArea
algılanan sınırlarını ayarlamak içinapp:startBoundOffset
,app:endBoundOffset
,app:topBoundOffset
,app:bottomBoundOffset
,app:horizontalBoundOffset
veapp:verticalBoundOffset
kullanın. - ( Android 11 QPR3, Android 11 Araba, Android 12 )
Verilen yönlerde bitişik birFocusArea
(veya alanların) kimliğini açıkça belirtmek içinapp:nudgeLeft
,app:nudgeRight
,app:nudgeUp
veapp:nudgeDown
kullanın. Varsayılan olarak kullanılan geometrik arama istenen hedefi bulamadığında bunu kullanın.
Dürtme genellikle Odak Alanları arasında gezinir. Ancak dürtme kısayollarıyla, dürtme bazen ilk önce bir FocusArea
içinde gezinir, böylece kullanıcının bir sonraki FocusArea
gitmek için iki kez dürtme yapması gerekebilir. Aşağıdaki örnekte olduğu gibi, FocusArea
uzun bir liste ve onu takip eden bir Kayan Eylem Düğmesi içerdiğinde, kaydırma kısayolları kullanışlıdır:
Dürtme kısayolu olmasaydı, kullanıcının FAB'a ulaşmak için tüm listeyi döndürmesi gerekecekti.
Odak vurgulama özelleştirmesi
Yukarıda belirtildiği gibi, RotaryService
Android çerçevesinin mevcut görüş odağı konsepti üzerine kurulmuştur. Kullanıcı dönüp dürttüğünde, RotaryService
odağı hareket ettirerek bir görünüme odaklanır ve diğerinin odağını kaldırır. Android'de bir görünüme odaklanıldığında görünüm:
- Kendi odak vurgusunu belirlemiş olan Android, görünümün odak vurgusunu çizer.
- Bir odak vurgusu belirtmez ve varsayılan odak vurgusu devre dışı bırakılmaz; Android, görünüm için varsayılan odak vurgusunu çizer.
Dokunma için tasarlanan 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ştiricileri, kullandıkları tema Theme.DeviceDefault
öğesinden türetildiğinde bunu alır.
Tutarlı bir kullanıcı deneyimi için mümkün olduğunda varsayılan odak vurgusunu kullanın. Özel şekilli (örneğin, yuvarlak veya hap şeklinde) bir odak vurgulamasına ihtiyacınız varsa veya Theme.DeviceDefault
öğesinden türetilmemiş bir tema kullanıyorsanız, kendi odak vurgunuzu belirlemek için car-ui-library kaynaklarını kullanın. her görünüm.
Bir görünüm için özel bir odak vurgusu belirlemek üzere, görünümün arka plan veya ön plan çizilebilirliğini, görünüme odaklanıldığında farklılık gösteren bir çizilebilir olarak değiştirin. Genellikle arka planı değiştirirsiniz. Aşağıdaki çizilebilir kare görünüm için arka plan olarak kullanıldığında yuvarlak odaklı bir vurgu 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, belirledikleri varsayılan odak vurgusuyla tutarlı olacak şekilde bunları geçersiz kılar. Bu, kullanıcı özel odak vurgusu olan bir görünüm ile varsayılan odak vurgusu olan bir görünüm arasında gezindiğinde odak vurgu renginin, kontur genişliğinin vb. değişmemesini sağlar. Son öğe dokunmak için kullanılan bir dalgalanmadır. Kalın kaynaklar için kullanılan varsayılan değerler aşağıdaki gibi görünür:
Ek olarak, aşağıdaki örnekte olduğu gibi, bir düğmeye kullanıcının dikkatini çekmek için düz bir arka plan rengi verildiğinde, özel odak vurgulaması çağrılır. Bu, odak vurgusunun görülmesini zorlaştırabilir. Bu durumda ikincil renkleri kullanarak özel bir odak vurgusu belirtin:
- ( Android 11 QPR3, Android 11 Araba, 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
Örneğin:
Odaklanmış, basılmamış | Odaklanmış, basılmış |
Döner kaydırma
Uygulamanız RecyclerView
kullanıyorsa bunun yerine CarUiRecyclerView
kullanmanız GEREKİR. Bu, bir OEM'in özelleştirmesinin tüm CarUiRecyclerView
için geçerli olması nedeniyle kullanıcı arayüzünüzün diğerleriyle tutarlı olmasını sağlar.
Listenizdeki öğelerin tümü odaklanabiliyorsa başka bir şey yapmanıza gerek yoktur. Döner gezinme, odağı listedeki öğeler arasında hareket ettirir ve yeni odaklanılan öğeyi görünür hale getirmek için liste kaydırılır.
( Android 11 QPR3, Android 11 Araba, Android 12 )
Odaklanabilen ve odaklanamayan öğelerin bir karışımı varsa veya tüm öğeler odaklanılamazsa, döner kaydırmayı etkinleştirebilirsiniz; bu, kullanıcının döner denetleyiciyi kullanarak odaklanamayan öğeleri atlamadan listede kademeli olarak ilerlemesine olanak tanır. Döner kaydırmayı etkinleştirmek için app:rotaryScrollEnabled
niteliğini true
olarak ayarlayın.
( Android 11 QPR3, Android 11 Araba, Android 12 )
CarUiUtils
setRotaryScrollEnabled()
yöntemiyle, av CarUiRecyclerView
dahil herhangi bir kaydırılabilir görünümde döner kaydırmayı etkinleştirebilirsiniz. Bunu yaparsanız şunları yapmanız gerekir:
- Odaklanabilir alt görünümlerinden hiçbiri görünür olmadığında odaklanılabilmesi için kaydırılabilir görünümü odaklanabilir hale getirin,
- Kaydırılabilir görünümün odaklanmış gibi görünmemesi için
setDefaultFocusHighlightEnabled(false)
öğesini çağırarak kaydırılabilir görünümdeki varsayılan odak vurgusunu devre dışı bırakın, -
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
çağrılarak kaydırılabilir görünümün alt öğelerinden önce odaklanıldığından emin olun. - Kaydırılacak mesafeyi ve yönü (işaret boyunca) belirtmek için
SOURCE_ROTARY_ENCODER
veAXIS_VSCROLL
veyaAXIS_HSCROLL
ile MotionEvents'i dinleyin.
CarUiRecyclerView
döner kaydırma etkinleştirildiğinde ve kullanıcı odaklanılabilir görünümlerin bulunmadığı bir alana döndüğünde, kaydırma çubuğu sanki kaydırma çubuğunun odaklandığını belirtmek istercesine griden maviye döner. İsterseniz benzer bir etki uygulayabilirsiniz.
MotionEvent'ler, kaynak haricinde fare üzerindeki kaydırma tekerleği tarafından oluşturulanlarla aynıdır.
Doğrudan manipülasyon modu
Normalde, dürtmeler ve döndürme kullanıcı arayüzünde gezinirken, Orta düğmeye basıldığında harekete geçilir, ancak bu her zaman böyle değildir. Örneğin, bir kullanıcı alarm ses düzeyini ayarlamak isterse, ses düzeyi kaydırıcısına gitmek için döner denetleyiciyi kullanabilir, Orta düğmeye basabilir, alarm ses düzeyini ayarlamak için denetleyiciyi döndürebilir ve ardından navigasyona geri dönmek için Geri düğmesine basabilir. . Buna doğrudan manipülasyon (DM) modu denir. Bu modda, döner denetleyici gezinmek yerine doğrudan görünümle etkileşimde bulunmak için kullanılır.
DM'yi iki yoldan biriyle uygulayın. Yalnızca döndürme işlemini gerçekleştirmeniz gerekiyorsa ve değiştirmek istediğiniz görünüm ACTION_SCROLL_FORWARD
ve ACTION_SCROLL_BACKWARD
AccessibilityEvent
öğelerine uygun şekilde yanıt veriyorsa, basit mekanizmayı kullanın. Aksi takdirde gelişmiş mekanizmayı kullanın.
Basit mekanizma sistem pencerelerindeki tek seçenektir; uygulamalar her iki mekanizmayı da kullanabilir.
Basit mekanizma
( Android 11 QPR3, Android 11 Araba, Android 12 )
Uygulamanız DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable)
çağırmalıdır. RotaryService
kullanıcının DM modunda olduğunu algılar ve kullanıcı bir görünüme odaklanmışken Ortadaki düğmeye bastığında DM moduna girer. DM modundayken, rotasyonlar ACTION_SCROLL_FORWARD
veya ACTION_SCROLL_BACKWARD
işlemini gerçekleştirir ve kullanıcı Geri düğmesine bastığında DM modundan çıkar. Basit mekanizma, DM moduna girerken ve çıkarken görünümün seçilen durumunu değiştirir.
Kullanıcının DM modunda olduğuna dair görsel bir ipucu sağlamak için görünümünüzün seçildiğinde farklı görünmesini sağlayın. Örneğin, android:state_selected
true
olduğunda arka planı değiştirin.
Gelişmiş mekanizma
Uygulama, RotaryService
DM moduna ne zaman girip çıkacağını belirler. Tutarlı bir kullanıcı deneyimi için, DM görünümü odaklıyken Orta düğmeye basıldığında DM moduna girilmeli ve Geri düğmesi DM modundan çıkılmalıdır. Ortadaki düğme ve/veya itme kullanılmazsa, bunlar 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 bir
KEYCODE_DPAD_CENTER
olayını dinlemeli ve DM modundan çıkmak için birKEYCODE_BACK
olayını dinlemeli ve her durumdaDirectManipulationHelper.enableDirectManipulationMode()
öğesini çağırmalıdır. Bu etkinlikleri dinlemek için aşağıdakilerden birini yapın:- Bir
OnKeyListener
kaydedin. veya, - Görünümü genişletin ve ardındandispatchKeyEvent
dispatchKeyEvent()
yöntemini geçersiz kılın.
- Bir
- Görünümün dürtüklemeleri işlemesi gerekiyorsa, dürtme olaylarını (
KEYCODE_DPAD_UP
,KEYCODE_DPAD_DOWN
,KEYCODE_DPAD_LEFT
veyaKEYCODE_DPAD_RIGHT
) dinlemeniz GEREKİR. - Görünüm rotasyonu işlemek istiyorsa,
MotionEvent
dinlemeli veAXIS_SCROLL
rotasyon sayısını almalıdır. Bunu yapmanın birkaç yolu vardır:- Bir
OnGenericMotionListener
kaydedin. - Görünümü genişletin ve
dispatchTouchEvent()
yöntemini geçersiz kılın.
- Bir
- DM modunda kalmayı önlemek için, görünümün ait olduğu Parça veya Etkinlik etkileşimli olmadığında DM modundan çıkılmalıdır.
- Görünümün DM modunda olduğunu belirten görsel bir ipucu sağlamalıdır.
Bir haritayı kaydırmak ve yakınlaştırmak için DM modunu kullanan özel görünümün bir ö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.
Etkinlik Görünümü
ActivityView kullanırken:
-
ActivityView
odaklanabilir olmamalıdır. - ( Android 11 QPR3, Android 11 Araba, Android 11'de kullanımdan kaldırıldı )
ActivityView
içeriğinin ilk odaklanılabilir görünüm olarak birFocusParkingView
içermesi ZORUNLU veapp:shouldRestoreFocus
niteliğininfalse
olması ZORUNLUDUR. -
ActivityView
içeriğindeandroid:focusByDefault
görünümü olmamalıdır.
Kullanıcı açısından, ActivityView'lerin, odak alanlarının ActivityView'leri kapsayamaması dışında gezinme üzerinde hiçbir etkisi olmamalıdır. Başka bir deyişle, ActivityView
içinde ve dışında içeriğe sahip tek bir odak alanınız olamaz. ActivityView
öğenize herhangi bir FocusAreas eklemezseniz ActivityView
içindeki görünüm hiyerarşisinin kökü örtülü bir odak alanı olarak kabul edilir.
Basılı tutulduğunda çalışan düğmeler
Çoğu düğme, tıklandığında bazı eylemlere neden olur. Bunun yerine bazı düğmeler basılı tutulduğunda çalışır. Örneğin, Hızlı İleri ve Geri Sarma düğmeleri genellikle basılı tutulduğunda çalışır. Bu tür düğmelerin döner desteği desteklemesi için KEYCODE_DPAD_CENTER
KeyEvents
aşağıdaki gibi 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; });
mRunnable
bir eylem (geri sarma gibi) gerçekleştirdiği ve kendisini bir gecikmeden sonra çalıştırılacak şekilde programladığı.
Dokunma modu
Kullanıcılar, bir arabadaki ana üniteyle iki şekilde etkileşim kurmak için döner denetleyiciyi kullanabilir; döner denetleyiciyi kullanarak veya ekrana dokunarak. Döner denetleyiciyi kullanırken odaklanılabilir görünümlerden biri vurgulanır. Ekrana dokunduğunuzda odak vurgusu görünmüyor. Kullanıcı istediği zaman bu giriş modları arasında geçiş yapabilir:
- Döndürme → dokunma. Kullanıcı ekrana dokunduğunda odak vurgusu kaybolur.
- → Döndür öğesine dokunun. Kullanıcı Ortadaki düğmeyi ittiğinde, döndürdüğünde veya bastığında odak vurgusu görünür.
Geri ve Ana Sayfa düğmelerinin giriş modu üzerinde hiçbir etkisi yoktur.
Android'in mevcut dokunmatik mod konseptinde döner bindirmeler. Kullanıcının hangi giriş modunu kullandığını belirlemek için View.isInTouchMode()
kullanabilirsiniz. Değişiklikleri dinlemek için OnTouchModeChangeListener
kullanabilirsiniz. Bu, kullanıcı arayüzünüzü mevcut giriş moduna göre özelleştirmek için kullanılabilse de, 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 odaklanabilen görünümlerin olması yaygındır. Örneğin, her ikisi de odaklanabilen ImageButton
çevresinde FrameLayout
olabilir. Bu, dokunmaya zarar vermez 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önerek kullanıcı deneyiminin kötü olmasına neden olabilir. İyi bir kullanıcı deneyimi için Google, dış görünümü veya iç görünümü odaklanabilir hale getirmenizi, ancak ikisini birden yapmamanızı önerir.
Döner denetleyici aracılığıyla basıldığında bir düğme veya anahtar odağı kaybederse aşağıdaki koşullardan biri geçerli olabilir:
- Düğmeye basılması nedeniyle düğme veya anahtar (kısa süreli veya süresiz olarak) devre dışı bırakılıyor. Her iki durumda da bu sorunu çözmenin iki yolu vardır:
-
android:enabled
durumunutrue
olarak bırakın ve düğmeyi grileştirmek veya Özel Durum bölümünde açıklandığı gibi geçiş yapmak için özel bir durum kullanın. - Düğmeyi veya anahtarı çevrelemek için bir kapsayıcı kullanın ve kapsayıcıyı düğme veya anahtar yerine odaklanabilir 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 gerçekleştirilen eylem, mevcut eylemlerin yenilenmesini tetikleyerek yeni düğmelerin mevcut düğmelerin yerini almasına neden olabilir. Bu sorunu çözmenin 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ıdaki gibi düğmenin veya anahtarın etrafına odaklanabilir bir kapsayıcı ekleyin.
DönerOyun Alanı
RotaryPlayground
, rotary için bir referans uygulamasıdır. Döner özellikleri uygulamalarınıza nasıl entegre edeceğinizi öğrenmek için bunu kullanın. RotaryPlayground
emülatör yapılarında ve Android Automotive OS (AAOS) çalıştıran cihazlara yönelik yapılarda bulunur.
-
RotaryPlayground
deposu:packages/apps/Car/tests/RotaryPlayground/
- Sürümler: Android 11 QPR3, Android 11 Car ve Android 12
RotaryPlayground
uygulaması sol tarafta aşağıdaki sekmeleri gösterir:
- Kartlar. Odaklanamayan öğeleri ve metin girişini atlayarak odak alanlarında gezinmeyi deneyin.
- Doğrudan manipülasyon. Basit ve gelişmiş doğrudan manipülasyon modunu destekleyen widget'ları test edin. Bu sekme özellikle uygulama penceresinde doğrudan değişiklik yapmak içindir.
- Sistem Kullanıcı Arayüzü Manipülasyonu. Yalnızca basit doğrudan manipülasyon modunun desteklendiği sistem pencerelerinde doğrudan manipülasyonu destekleyen test widget'ları.
- Kafes. Kaydırma ile z-modeli döner gezinmeyi test edin.
- Bildiri. Dikkat bildirimlerine girip çıkmayı test edin.
- Taslak. Odaklanabilir ve odaklanamayan içeriklerin bir karışımını kaydırmayı test edin.
- Web Görünümü. Bir
WebView
bağlantılar arasında gezinmeyi test edin. - Özel
FocusArea
.FocusArea
özelleştirmesini test edin:- Etrafına sarmak.
-
android:focusedByDefault
veapp:defaultFocus
. - Açık dürtme hedefleri.
- Kısayolları sürükleyin.
- Odaklanabilir görünümlerin olmadığı
FocusArea
.