Viele zusammensetzbare Funktionen unterstützen das Tippen oder Klicken und enthalten ein
onClick
Lambda. Sie können beispielsweise eine anklickbare Surface
erstellen, die
umfasst alle Material Design-Verhaltensweisen, die für die Interaktion mit Oberflächen geeignet sind:
Surface(onClick = { /* handle click */ }) { Text("Click me!", Modifier.padding(24.dp)) }
Klicks sind jedoch nicht die einzige Möglichkeit, wie Nutzende mit zusammensetzbaren Funktionen interagieren können. Diese Seite konzentriert sich auf Gesten, die einen einzelnen Zeiger umfassen, dass dieser Zeiger für die Verarbeitung dieses Ereignisses nicht von Bedeutung ist. Die folgenden sind folgende Arten von Gesten aufgeführt:
Touch-Geste |
Beschreibung |
Tippen (oder klicken) |
Zeiger nach unten und dann nach oben |
Doppeltippen |
Zeiger geht nach unten, nach oben, nach unten, nach oben |
Lange drücken |
Zeiger fällt nach unten und wird länger gehalten |
Presse |
Zeiger fällt nach unten |
Auf Antippen oder Klicken reagieren
clickable
ist ein häufig verwendeter Modifikator, mit dem eine zusammensetzbare Funktion auf
Tippen oder Klicken. Dieser Modifikator bietet zusätzliche Funktionen, wie z. B. Unterstützung für
Fokus, Maus und Eingabestift bewegt, sowie eine anpassbare visuelle Anzeige, wenn
gedrückt. Der Modifikator reagiert auf „Klicks“ im weitesten Sinne des Wortes –
nur mit Maus oder Finger, sondern auch per Tastatureingabe oder bei
Bedienungshilfen nutzen.
Stellen Sie sich ein Bildraster vor, bei dem ein Bild im Vollbildmodus angezeigt wird, darauf klickt:
Sie können jedem Element im Raster den clickable
-Modifikator hinzufügen, um dies zu implementieren
Verhalten:
@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 } ) } }
Der clickable
-Modifikator bietet außerdem zusätzliche Funktionen:
interactionSource
undindication
, die standardmäßig eine Welle zeichnen, wenn ein Nutzende auf die zusammensetzbare Funktion. Informationen zum Anpassen finden Sie unter Handhabung von Interaktionen angezeigt.- Erlaubt Bedienungshilfen, mit dem Element zu interagieren, indem die Semantik.
- Unterstützt die Interaktion über Tastatur oder Joystick, indem Fokus und Drücken der Anzeige möglich sind
Enter
oder die Mitte des Steuerkreuzes, um zu interagieren. - Element schwebbar machen, damit es auf das Bewegen der Maus oder des Eingabestifts reagiert darüber sprechen.
Lange drücken, um Kontextmenü einzublenden
Über combinedClickable
können Sie Funktionen für Doppeltippen oder langes Drücken in
neben dem normalen Klickverhalten. Mit combinedClickable
können Sie Folgendes anzeigen:
Kontextmenü, wenn ein Nutzer ein Rasterbild berührt und hält:
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 } ) }
Als Best Practice sollten Sie haptisches Feedback einbeziehen,
Elemente lange drücken. Deshalb enthält das Snippet
Aufruf von performHapticFeedback
.
Zusammensetzbare Funktion durch Antippen eines Scrums schließen
In den Beispielen oben fügen clickable
und combinedClickable
nützliche
Funktionalität hinzufügen. Sie liefern visuelle
Hinweise auf die Interaktion,
auf das Bewegen des Mauszeigers reagieren und Unterstützung für Fokus, Tastatur und Bedienungshilfen bieten. Aber
ist dieses zusätzliche Verhalten
nicht immer erwünscht.
Sehen wir uns den Bildschirm mit den Bilddetails an. Der Hintergrund sollte halbtransparent sein. Der Nutzer sollte in der Lage sein, auf diesen Hintergrund zu tippen, um den Detailbildschirm zu schließen:
In diesem Fall sollte der Hintergrund
keinen visuellen Hinweis auf die
sollte nicht auf den Mauszeiger
reagiert werden, nicht fokussierbar sein
die Reaktion auf Tastatur- und Eingabehilfenereignisse,
zusammensetzbar. Anstatt zu versuchen, das Verhalten von clickable
anzupassen, können Sie
auf eine niedrigere Abstraktionsebene herunter und verwenden Sie direkt den pointerInput
-Modifikator
in Kombination mit der detectTapGestures
-Methode:
@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)) ) }
Als Schlüssel des pointerInput
-Modifikator übergeben Sie das Lambda onClose
. Dieses
führt die Lambda-Funktion automatisch noch einmal aus und sorgt dafür, dass der richtige Callback aufgerufen wird.
wenn Nutzende auf das Gitter tippen.
Zum Zoomen doppeltippen
Manchmal enthalten clickable
und combinedClickable
nicht genügend Informationen
um richtig auf die Interaktion zu reagieren. Zusammensetzbare Funktionen
Zugriff auf die Position innerhalb der Grenzen der zusammensetzbaren Funktion benötigen, an der die Interaktion
stattfand.
Sehen wir uns noch einmal den Bildschirm mit den Bilddetails an. Es empfiehlt sich, kann das Bild durch Doppeltippen vergrößert werden:
Wie im Video zu sehen ist, wird um die Position des Tippens herum herangezoomt
. Das Ergebnis ist anders, wenn wir den linken Teil des Bildes heranzoomen.
und zum richtigen Teil. Wir können den pointerInput
-Modifikator in einer Kombination
detectTapGestures
, um die Tippposition in unser
Berechnung:
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 } )
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Touch-Gesten
- Material Design 2 in Compose
- Kotlin für Jetpack Compose