Dokunup basın

Birçok composable'da dokunma veya tıklama desteği yerleşik olarak sunuluyor. onClick lambda. Örneğin, tıklanabilir bir Surface oluşturabilirsiniz. yüzeylerle etkileşime uygun tüm Materyal Tasarım davranışlarını içerir:

Surface(onClick = { /* handle click */ }) {
    Text("Click me!", Modifier.padding(24.dp))
}

Ancak kullanıcıların composable'larla etkileşimde bulunabilmesinin tek yolu tıklama değildir. Bu sayfa tek bir işaretçi içeren hareketlere odaklanır ve söz konusu etkinliğin işlenmesi açısından önemli değildir. Aşağıdakiler tablosunda aşağıdaki hareket türleri listelenmiştir:

Hareket

Açıklama

Dokunun (veya tıklayın)

İşaretçi aşağı ve ardından 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ğı iniyor

Dokunma veya tıklamaya yanıt verin

clickable, şunlara composable tepki veren, yaygın olarak kullanılan bir değiştiricidir unutmayın. Bu değiştirici, üzerine gelme, fare ve ekran kaleminin üzerine gelme gibi özelleştirilebilir görsel gösterge, basıldı. Değiştirici "tıklamalara" tepki verir bir anlam ifade etmese bile, yalnızca fare veya parmakla değil, aynı zamanda klavye girişi aracılığıyla veya erişilebilir hale getirebilirsiniz.

Bir kullanıcı tıkladığında resmin tam ekran gösterildiği bir resim ızgarası düşünün tıkladığında:

Bunu uygulamak için tablodaki her öğeye clickable değiştiriciyi ekleyebilirsiniz davranış:

@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ştiricisi ek davranışlar da ekler:

  • interactionSource ve indication. Bunlar varsayılan olarak kullanıcı composable'a dokunduğunda. Bunların nasıl özelleştirileceğini Kullanıcı yönetimi etkileşimleri sayfasında gösterilir.
  • Şu ayarı ayarlayarak erişilebilirlik hizmetlerinin öğeyle etkileşimde bulunmasına izin verir: anlamsal bilgiler sağlar.
  • Odaklanmaya izin verip bastırarak klavye veya kontrol çubuğu etkileşimini destekler Etkileşim için Enter veya d-pad'in ortasına dokunun.
  • Öğenin üzerine gelinebilir, böylece fare veya ekran kaleminin üzerine gelmesine yanıt verebilir. üzerine düşünün.

İçeriğe dayalı içerik menüsü göstermek için uzun basın

combinedClickable, iki kez dokunma veya uzun basma davranışı eklemenize olanak tanır. normal tıklama davranışına ek olarak. combinedClickable kullanarak Kullanıcı bir ızgara resme dokunup basılı tuttuğunda içerik menüsü:

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ı oyuna girdiğinde dokunsal geribildirimi öğelere uzun basar; bu nedenle snippet, performHapticFeedback çağrısı.

Parmağınıza dokunarak bir composable'ı kapatabilirsiniz

Yukarıdaki örneklerde clickable ve combinedClickable, şu anlamlara gelir: işlevlerinizi geliştirebilirsiniz. Etkileşimin görsel bir göstergesidirler, fareyle üzerine gelmeye yanıt verir ve odak, klavye ve erişilebilirlik desteği içerir. Ama bu ekstra davranış her zaman istenen bir durum değildir.

Resim ayrıntıları ekranına bakalım. Arka plan yarı şeffaf olmalıdır. Kullanıcı ayrıntı ekranını kapatmak için ilgili arka plana dokunabilmelidir:

Bu durumda, ilgili arka planda herhangi bir görsel etkileşim, fareyle üzerine gelmeye yanıt vermemeli, odaklanılabilir olmamalıdır klavye ve erişilebilirlik etkinliklerine verilen tepki, tipik bir composable'dan bahsetmek istiyorum. clickable davranışını uyarlamaya çalışmak yerine, değişiklikleri daha alt soyutlama seviyesine kadar inip doğrudan pointerInput değiştiricisini kullanın. detectTapGestures yöntemiyle birlikte:

@OptIn(ExperimentalComposeUiApi::class)
@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 tuşu olarak onClose lambda'yı geçirirsiniz. Bu lambda'yı otomatik olarak yeniden yürüterek doğru geri çağırmanın çağrılmasını sağlar. Kullanıcı kumaşa dokunduğunda.

Yakınlaştırmak için iki kez dokunun

Bazen clickable ve combinedClickable yeterli bilgi içermiyor etkileşime doğru yanıt verebilmek için iyi bir konumdasınız. Örneğin, composables composable'ın sınırları dahilinde, bu etkileşimlerin gerçekleşeceği gerçekleştirilmiştir.

Resim ayrıntıları ekranına tekrar bakalım. En iyi uygulamalardan biri, iki kez dokunarak resmi yakınlaştırabilirsiniz:

Videoda görebileceğiniz gibi, dokunma hareketinin olduğu yerde yakınlaştırma yapılır. unutmayın. Resmin sol kısmını yakınlaştırdığımızda sonuç farklı oluyor emin olmanız gerekir. pointerInput değiştiricisini birlikte kullanabiliriz dokunma konumunu video reklam öğelerimize eklemek için detectTapGestures hesaplama:

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
        }
)

ziyaret edin.