Bazen öğelerin varsayılan odaklanma davranışını geçersiz kılmak ekranda görebilirsiniz. Örneğin, composable'ları gruplandırmak, geliştirmelerin önlenmesi için belirli bir composable'a odaklanma, bire odaklanmayı isteme, odağı yakalama veya serbest bırakma ya da giriş veya çıkışta odağı yönlendirme. Bu bölümünde, varsayılan değerler istemediğinizde odak davranışını nasıl değiştireceğiniz açıklanmaktadır. gerekiyor.
Odak gruplarıyla tutarlı gezinme sağlayın
Bazen Jetpack Compose, sonraki öğe için doğru olanı hemen
sekmeli gezinme, özellikle de sekmeler ve Composables
gibi karmaşık üst öğeler olduğunda
devreye girer.
Odaklı arama genellikle Composables
bildirim sırasını takip etse de
bazı durumlarda bu mümkün değildir. Örneğin, Composables
hiyerarşi, tamamen görünür olmayan yatay bir kaydırılabilir öğedir. Bu bilginin gösterildiği yer:
aşağıdaki örneğe bakın.
Jetpack Compose, öğenin başlangıcına en yakın olan bir sonraki öğeye odaklanmaya karar verebilir. aşağıdaki gösterildiği gibi, beklediğiniz yoldan devam etmek yerine tek yönlü gezinme:
![Yatay üst gezinme menüsünü ve altındaki öğelerin listesini gösteren uygulama animasyonu.](https://developer.android.com/static/develop/ui/compose/images/touchinput/one_directional_navigation_1.gif?authuser=5&hl=tr)
Bu örnekte, geliştiricilerin kasıtlı olmadığı açıkça bellidir: Çikolatalar sekmesinden aşağıdaki ilk resme geçin ve Pastalar sekmesi. Bunun yerine, odak noktası olana kadar sekmelerde son sekmeye geçip iç içeriğe odaklanın:
![Yatay üst gezinme menüsünü ve altındaki öğelerin listesini gösteren uygulama animasyonu.](https://developer.android.com/static/develop/ui/compose/images/touchinput/one_directional_navigation_2.gif?authuser=5&hl=tr)
Bir grup composable'a odaklanılmasının önemli olduğu durumlarda
sırayla, önceki örnekteki Sekme satırında olduğu gibi,
focusGroup()
değiştiricisine sahip bir üst öğedeki Composable
:
LazyVerticalGrid(columns = GridCells.Fixed(4)) { item(span = { GridItemSpan(maxLineSpan) }) { Row(modifier = Modifier.focusGroup()) { FilterChipA() FilterChipB() FilterChipC() } } items(chocolates) { SweetsCard(sweets = it) } }
İki yönlü gezinme, verilen öğe için en yakın composable'ı
yön: Başka bir gruptaki öğe, tamamen görünür olmayan bir öğeden daha yakınsa
öğe geçerli grupta yer alıyorsa, gezinme en yakın öğeyi seçer. Bunu önlemek için
focusGroup()
değiştiricisini uygulayabilirsiniz.
FocusGroup
, odak açısından tüm bir grubun tek bir varlık gibi görünmesini sağlar.
ancak grup odakta kalmayan en yakın çocuk
odaklanılır. Bu şekilde, gezinme, tamamen görünmeyen sayfalara gitmesini
öğesine dokunun.
Bu durumda, üç FilterChip
örneğine
SweetsCard
öğe, SweetsCards
kullanıcı ve bazı FilterChip
gizlenmiş olabilir. Bunun nedeni,
focusGroup
değiştiricisi, odak yöneticisine öğelerin gösterildiği sırayı ayarlamasını söyler
Böylece, gezinmeyi kullanıcı arayüzüyle daha kolay ve tutarlı olacak şekilde odakladık.
focusGroup
değiştiricisi kullanılmadığında, FilterChipC
görünür değilse odaklan
navigasyon en son onu seçer. Ancak böyle bir değiştirici eklemek,
bulunabilir, ancak FilterChipB
sonrasında odaklanmaya başlar,
beklentiler yer alıyor.
Bir composable'ı odaklanılabilir hale getirme
Düğme veya composable gibi bazı composable'lara tasarım odaklı
clickable
değiştiricisi var. Özellikle eklemek istediğiniz
odaklanma davranışını bir composable'a dönüştürmek için focusable
değiştiricisini kullanırsınız:
var color by remember { mutableStateOf(Green) } Box( Modifier .background(color) .onFocusChanged { color = if (it.isFocused) Blue else Green } .focusable() ) { Text("Focusable 1") }
Bir composable'ı odaklanılamaz hale getirme
Öğelerinizden bazılarının katılmaması gereken durumlar olabilir.
ön plana çıkarırım. Bu nadir durumlarda, canFocus property
bir Composable
öğesinin odaklanılabilir olmasını engeller.
var checked by remember { mutableStateOf(false) } Switch( checked = checked, onCheckedChange = { checked = it }, // Prevent component from being focused modifier = Modifier .focusProperties { canFocus = false } )
FocusRequester
ile klavye odağı iste
Bazı durumlarda belirli bir soruya yanıt olarak kullanıcı etkileşimi. Örneğin, bir kullanıcıya yeniden başlatmak isteyip istemediğini ya da "evet"e basarlarsa ilk alana yeniden odaklamak iletişim kurabilirsiniz.
İlk yapmanız gereken, bir FocusRequester
nesnesini
klavye odağını taşımak istediğiniz composable'ı seçin. Aşağıdaki kodda
snippet'te bir FocusRequester
nesne, bir TextField
Modifier.focusRequester
adlı değiştirici:
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) )
Gerçek odaklanma istekleri göndermek için FocusRequester'ın requestFocus
yöntemini çağırabilirsiniz. Bu yöntemi bir Composable
bağlamı dışında çağırmanız gerekir
(aksi takdirde, her yeniden oluşturmada yeniden yürütülür). Aşağıdaki snippet
düğme açıkken klavye odağını hareket ettirmesi için sistemin nasıl istekte bulunulacağını gösterir
tıklandı:
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) ) Button(onClick = { focusRequester.requestFocus() }) { Text("Request focus on TextField") }
Odağı yakala ve bırak
Kullanıcılarınızı uygulamanıza doğru verileri sağlamaları için yönlendirmek amacıyla odaktan yararlanabilirsiniz. görevini yerine getirmesi gerekiyorsa (örneğin, geçerli bir e-posta adresi veya telefon almak) sayı. Hata durumları kullanıcılarınızı neler olduğu konusunda bilgilendirse de alana kadar odaklanması için hatalı bilgi içeren alana düzeltildi.
Odağı yakalamak için captureFocus()
yöntemini çağırabilir ve
aşağıdaki gibi, bunun yerine freeFocus()
yöntemiyle yayınlayın
örnek:
val textField = FocusRequester() TextField( value = text, onValueChange = { text = it if (it.length > 3) { textField.captureFocus() } else { textField.freeFocus() } }, modifier = Modifier.focusRequester(textField) )
Odak değiştiricilerin önceliği
Modifiers
, yalnızca tek bir alt öğesi olan öğeler olarak görülebilir. Bu nedenle, sıraya
soldaki (veya üstteki) her Modifier
etiketi, sonraki URL'yi takip eden Modifier
öğesini
sağda (veya altında). Bu, ikinci Modifier
öğesinin
Böylece, iki focusProperties
tanımlanırken yalnızca en üstteki
ve aşağıdakilerden biri en üstte yer aldığından bir eser.
Kavramı daha iyi açıklamak için aşağıdaki kodu inceleyin:
Modifier .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
Bu durumda, doğru odak noktası olarak item2
değerini gösteren focusProperties
bir öncekinde bulunduğu için kullanılmamalıdır; dolayısıyla item1
bir tanesi kullanıldı.
Bu yaklaşımdan yararlanan bir ebeveyn de davranışı varsayılan olarak sıfırlayabilir
FocusRequester.Default
kullanılarak:
Modifier .focusProperties { right = Default } .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
Üst öğenin aynı değiştirici zincirinin parçası olması gerekmez. Ebeveyn
composable, bir alt composable'ın odak özelliğinin üzerine yazabilir. Örneğin,
düğmenin odaklanılamamasına neden olan şu FancyButton
dikkate alın:
@Composable fun FancyButton(modifier: Modifier = Modifier) { Row(modifier.focusProperties { canFocus = false }) { Text("Click me") Button(onClick = { }) { Text("OK") } } }
Kullanıcı, canFocus
öğesini true
olarak ayarlayarak bu düğmeyi tekrar odaklanabilir hale getirebilir:
FancyButton(Modifier.focusProperties { canFocus = true })
Her Modifier
gibi odakla ilgili olanlar da sıraya göre farklı davranır
açıklamanız gerekir. Örneğin, aşağıdaki gibi bir kod, Box
odaklanılabilir, ancak FocusRequester
bu odaklanılabilir öğe ile ilişkili değildir
odaklanılabilir öğeden sonra tanımlanır.
Box( Modifier .focusable() .focusRequester(Default) .onFocusChanged {} )
focusRequester
öğesinin ilk
odaklanılabilir; bu nedenle bu focusRequester
, hedefe
empatiyle yaklaşmak
çok önemlidir. Bunların hiçbiri yoksa herhangi bir yere işaret etmez.
Ancak Box
odaklanılabilir olduğundan (focusable()
değiştiricisi sayesinde),
iki yönlü gezinmeyi kullanarak gidebilirsiniz.
Başka bir örnek olarak, aşağıdakilerden biri onFocusChanged()
olarak kullanılabilir
değiştiricisi,
focusable()
veya focusTarget()
değiştiricileri.
Box( Modifier .onFocusChanged {} .focusRequester(Default) .focusable() ) |
Box( Modifier .focusRequester(Default) .onFocusChanged {} .focusable() ) |
Girişte veya çıkışta odağı yönlendir
Bazen, son derece özel bir gezinme türü sağlamanız gerekir. aşağıdaki animasyonda gösterildiği gibi:
![Yan yana yerleştirilmiş iki düğme sütununu gösteren ve bir sütundan diğerine odaklanılan bir ekran animasyonu.](https://developer.android.com/static/develop/ui/compose/images/touchinput/two_dimensional_navigation_1.gif?authuser=5&hl=tr)
Bunun nasıl oluşturulacağına geçmeden önce, varsayılan olarak
odaklı arama davranışının davranışını gösterir. Herhangi bir değişiklik yapılmadan,
d-pad'de DOWN
tuşuna (veya eşdeğeri) basarak Clickable 3
öğeye ulaşır
ok tuşu) ise odağı Column
sütununun altında görüntülenene taşır,
ve sağdaki grubu yoksayabilirsiniz. Herhangi bir
odaklanılabilir öğeler varsa, odak hiçbir yerde hareket etmez ancak
Clickable 3
Bu davranışı değiştirmek ve amaçlanan gezinmeyi sağlamak için
focusProperties
değiştiricisi, odaklamaya odaklanıldığında ne olacağını yönetmenize yardımcı olur.
araması Composable
kodunu girer veya çıkar:
val otherComposable = remember { FocusRequester() } Modifier.focusProperties { exit = { focusDirection -> when (focusDirection) { Right -> Cancel Down -> otherComposable else -> Default } } }
Belirli bir Composable
girildiğinde odak noktası bu noktaya yönlendirilebilir
veya hiyerarşinin belirli bir bölümünden çıkar. Örneğin, kullanıcı arayüzünde iki
sütuna giriyoruz ve ilk sütunun her işlenmesinde
ikinci odaklamaya geçer:
![Yan yana yerleştirilmiş iki düğme sütununu gösteren ve bir sütundan diğerine odaklanılan bir ekran animasyonu.](https://developer.android.com/static/develop/ui/compose/images/touchinput/two_dimensional_navigation_2.gif?authuser=5&hl=tr)
Bu GIF'te, odak Column
1'de Clickable 3 Composable
hedefine ulaştığında,
odaklanılan sonraki öğe başka bir Column
içinde Clickable 4
. Bu davranış
focusDirection
, enter
ve exit
ile birleştirilerek elde edilebilir
focusProperties
değiştiricisindeki değerler. İkisinin de lambdalara ihtiyacı var.
parametresi olarak odağın nereden geldiğini gösterir ve
FocusRequester
Bu lambda üç farklı şekilde davranabilir:
FocusRequester.Cancel
, odaklanmaya devam etmeyi durdururken
FocusRequester.Default
, davranışını değiştirmez. Bunun yerine
Başka bir Composable
öğesine bağlı FocusRequester
, odağı bu öğeye atlar
belirli Composable
.
Odak ilerleme yönünü değiştir
Odağı bir sonraki öğeye veya kesin bir yöne doğru ilerlemek için
onPreviewKey
değiştiricisinden yararlanıp LocalFocusManager
moveFocus
Değiştirici ile odağı geliştirebilirsiniz.
Aşağıdaki örnekte odak mekanizmasının varsayılan davranışı gösterilmektedir:
tab
tuşa basma algılandığında odak, odaktaki sonraki öğeye geçer
liste'ye dokunun. Bu genellikle yapılandırmanız gereken bir şey olmasa da önemlidir
varsayılan değerleri değiştirebilmek için sistemin iç işleyişini bilmek
gösterir.
val focusManager = LocalFocusManager.current var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.onPreviewKeyEvent { when { KeyEventType.KeyUp == it.type && Key.Tab == it.key -> { focusManager.moveFocus(FocusDirection.Next) true } else -> false } } )
Bu örnekte, focusManager.moveFocus()
işlevi odağı
belirtilen öğeye veya işlev parametresinde belirtilen yöne doğru kullanılabilir.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Odaklanmaya tepki verme
- E-posta Yazma'da odaklan
- Odak geçiş sırasını değiştirme