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:
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:
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 = remember { 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:
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:
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