Birçok bileşen, dokunma veya tıklama için yerleşik desteğe sahiptir ve bir onClick
lambda içerir. Örneğin, yüzeylerle etkileşime uygun tüm Material Design davranışlarını içeren tıklanabilir bir Surface
oluşturabilirsiniz:
Surface(onClick = { /* handle click */ }) { Text("Click me!", Modifier.padding(24.dp)) }
Ancak kullanıcıların, bileşenlerle etkileşime geçmesinin tek yolu tıklama değildir. Bu sayfada, tek bir işaretçi içeren ve bu işaretçinin konumunun ilgili etkinliğin işlenmesi açısından önemli olmadığı hareketler ele alınmaktadır. Aşağıdaki tabloda bu hareket türleri listelenmiştir:
Hareket |
Açıklama |
Dokunma (veya tıklama) |
İşaretçi aşağı ve sonra yukarı gider |
İki kez dokunun |
İşaretçi aşağı, yukarı, aşağı, yukarı gider |
Uzun basma |
İşaretçi aşağı iner ve daha uzun süre tutulur |
Basın |
İşaretçi aşağı gider |
Dokunma veya tıklama işlemlerine yanıt verme
clickable
, bir bileşenin dokunma veya tıklama işlemlerine tepki vermesini sağlayan yaygın bir değiştiricidir. Bu değiştirici, odaklanma, fare ve ekran kalemi üzerine gelme desteği ve basıldığında özelleştirilebilir görsel gösterge gibi ek özellikler de ekler. Değiştirici, "tıklamalara" kelimenin en geniş anlamıyla yanıt verir. Yalnızca fare veya parmakla değil, klavye girişi aracılığıyla veya erişilebilirlik hizmetleri kullanılırken gerçekleşen tıklama etkinliklerine de yanıt verir.
Kullanıcının tıkladığı bir resmin tam ekran gösterildiği bir resim ızgarası düşünün:
Bu davranışı uygulamak için clickable
değiştiriciyi ızgaradaki her öğeye ekleyebilirsiniz:
@Composable private fun ImageGrid(photos: List<Photo>) { var activePhotoId by rememberSaveable { mutableStateOf<Int?>(null) } LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier.clickable { activePhotoId = photo.id } ) } } if (activePhotoId != null) { FullScreenImage( photo = photos.first { it.id == activePhotoId }, onDismiss = { activePhotoId = null } ) } }
clickable
değiştirici, ek davranış da ekler:
interactionSource
veindication
, kullanıcı composable'a dokunduğunda varsayılan olarak bir dalga çizer. Bunları nasıl özelleştireceğinizi Kullanıcı etkileşimlerini yönetme sayfasında öğrenebilirsiniz.- Erişilebilirlik hizmetlerinin, anlam bilgisini ayarlayarak öğeyle etkileşime geçmesine olanak tanır.
- Odaklanma ve
Enter
tuşuna veya d-pad'in ortasına basarak etkileşime izin vererek klavye veya kontrol çubuğuyla etkileşimi destekler. - Fare veya ekran kaleminin üzerine geldiğinde yanıt vermesi için öğeyi fareyle üzerine gelinebilir hale getirin.
Bağlama dayalı içerik menüsü göstermek için uzun basın
combinedClickable
, normal tıklama davranışına ek olarak iki kez dokunma veya uzun basma davranışı eklemenizi sağlar. Kullanıcı bir ızgara resmine dokunup basılı tuttuğunda içerik menüsü göstermek için combinedClickable
simgesini kullanabilirsiniz:
var contextMenuPhotoId by rememberSaveable { mutableStateOf<Int?>(null) } val haptics = LocalHapticFeedback.current LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier .combinedClickable( onClick = { activePhotoId = photo.id }, onLongClick = { haptics.performHapticFeedback(HapticFeedbackType.LongPress) contextMenuPhotoId = photo.id }, onLongClickLabel = stringResource(R.string.open_context_menu) ) ) } } if (contextMenuPhotoId != null) { PhotoActionsSheet( photo = photos.first { it.id == contextMenuPhotoId }, onDismissSheet = { contextMenuPhotoId = null } ) }
En iyi uygulama olarak, kullanıcı öğelere uzun bastığında dokunma geri bildirimi eklemeniz gerekir. Bu nedenle snippet'te performHapticFeedback
çağrısı yer alır.
Bir örtüye dokunarak bir bileşiği kapatma
Yukarıdaki örneklerde clickable
ve combinedClickable
, bileşenlerinize yararlı işlevler ekler. Etkileşimde görsel bir gösterge gösterir, fareyle üzerine gelindiğinde yanıt verir ve odak, klavye ve erişilebilirlik desteği içerir. Ancak bu ek davranış her zaman istenmez.
Resim ayrıntıları ekranına bakalım. Arka plan yarı saydam olmalı ve kullanıcı, ayrıntılar ekranını kapatmak için bu arka plana dokunabilmelidir:
Bu durumda, bu arka planda etkileşimle ilgili herhangi bir görsel gösterge bulunmamalı, fareyle üzerine gelindiğinde yanıt verilmemeli, odaklanılabilir olmamalı ve klavye ile erişilebilirlik etkinliklerine verdiği yanıt, tipik bir kompozisyonun yanıtından farklı olmalıdır. clickable
davranışını uyarlamaya çalışmak yerine daha düşük bir soyutlama düzeyine inebilir ve detectTapGestures
yöntemiyle birlikte doğrudan pointerInput
değiştiriciyi kullanabilirsiniz:
@Composable private fun Scrim(onClose: () -> Unit, modifier: Modifier = Modifier) { val strClose = stringResource(R.string.close) Box( modifier // handle pointer input .pointerInput(onClose) { detectTapGestures { onClose() } } // handle accessibility services .semantics(mergeDescendants = true) { contentDescription = strClose onClick { onClose() true } } // handle physical keyboard input .onKeyEvent { if (it.key == Key.Escape) { onClose() true } else { false } } // draw scrim .background(Color.DarkGray.copy(alpha = 0.75f)) ) }
pointerInput
değiştiricisinin anahtarı olarak onClose
lambdasını iletirsiniz. Bu işlem, lambda'yı otomatik olarak yeniden yürütür ve kullanıcı scrim'e dokunduğunda doğru geri çağırma işlevinin çağrılmasını sağlar.
Yakınlaştırmak için iki kez dokunun
Bazen clickable
ve combinedClickable
, etkileşime doğru şekilde yanıt vermek için yeterli bilgi içermez. Örneğin, bileşenlerin etkileşimin gerçekleştiği bileşen sınırları içindeki konuma erişmesi gerekebilir.
Resim ayrıntıları ekranına tekrar göz atalım. En iyi uygulama, çift dokunarak resmi yakınlaştırmayı mümkün kılmaktır:
Videoda görebileceğiniz gibi, yakınlaştırma işlemi dokunma etkinliğinin konumu çevresinde gerçekleşir. Resmin sol kısmını yakınlaştırdığımızda elde edilen sonuç, sağ kısmını yakınlaştırdığımızdan farklıdır. Dokunma konumunu hesaplamamıza dahil etmek için pointerInput
değiştiricisini detectTapGestures
ile birlikte kullanabiliriz:
var zoomed by remember { mutableStateOf(false) } var zoomOffset by remember { mutableStateOf(Offset.Zero) } Image( painter = rememberAsyncImagePainter(model = photo.highResUrl), contentDescription = null, modifier = modifier .pointerInput(Unit) { detectTapGestures( onDoubleTap = { tapOffset -> zoomOffset = if (zoomed) Offset.Zero else calculateOffset(tapOffset, size) zoomed = !zoomed } ) } .graphicsLayer { scaleX = if (zoomed) 2f else 1f scaleY = if (zoomed) 2f else 1f translationX = zoomOffset.x translationY = zoomOffset.y } )
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Hareketleri anlama
- Oluşturma bölümündeki Material Design 2
- Jetpack Compose için Kotlin