An overview of
Compose provides several apis for implementing various gestures, including click, press, double click, long press, horizontal and vertical swipe, drag, two-finger pan, zoom and rotate, and nested happy effects
All kinds of gesture effect introduction
Click on the sign
code
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Box(modifier = Modifier
.size(200.dp)
.background(Color.Green)
.clickable {
App.toast("Clicked")
}, contentAlignment = Alignment.Center
) {
Text(text = "Click event")}}Copy the code
The effect
Single click, press, double click, and long press
code
@Composable
fun PointerView(a) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Box(
modifier = Modifier
.size(200.dp)
.background(Color.Green)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
App.toast("Single point event trigger")
},
onDoubleTap = {
App.toast("Double click event")
},
onPress = {
// app.toast (" press event ")
},
onLongPress = {
App.toast("Long press event")
}
)
}, contentAlignment = Alignment.Center
) {
Text(text = "Single click, double click, press, long press events")}}}Copy the code
instructions
Double click, click, long press will trigger the effect of press callback, pointerInput. DetectTapGestures
The effect
Horizontal and vertical sliding
code
val list = (0.255.)
Column(
Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Box(
Modifier
.fillMaxWidth(10f)
.height(100.dp)
.background(Color.Green)
.horizontalScroll(rememberScrollState()),
contentAlignment = Alignment.Center
) {
Text(
text = "Ananzhuo, welcome to follow the nuggets, public number, CSDN, share android knowledge, ananzhuo, welcome to follow the nuggets, public number, CSDN, share android knowledge, ananzhuo, welcome to follow the nuggets, public number, CSDN, share Android knowledge",
style = TextStyle(color = Color.White, fontSize = 20.sp, fontWeight = FontWeight.Bold)
)
}
repeat(40) {
Box(
Modifier
.height(80.dp)
.fillMaxWidth()
.background(Color(list.random(), list.random(), list.random())),
contentAlignment = Alignment.Center
) {
Text(text = it.toString(), style = TextStyle(color = Color.White, fontSize = 20.sp))
}
}
}
Copy the code
instructions
For any control, you only need to invoke two modifiers to achieve the sliding effect
.verticalScroll(rememberScrollState())
.horizontalScroll(rememberScrollState())
The effect
drag
code
var offsetX by remember {
mutableStateOf(0f)}var offsetY by remember {
mutableStateOf(0f)
}
Box(Modifier.fillMaxSize()) {
Box(
Modifier
.offset { IntOffset(offsetX.toInt(), offsetY.toInt()) }
.size(200.dp)
.background(Color.Green, shape = CircleShape)
.pointerInput(Unit) {
detectDragGestures(onDrag = { pointerInputChange: PointerInputChange, offset: Offset ->
pointerInputChange.consumeAllChanges()// Consumption slide
offsetX += offset.x
offsetY += offset.y
})
},
contentAlignment = Alignment.Center
) {
Text(text = "Tap slide circle")}}Copy the code
instructions
The effect
Multistage sliding
code
val list = (0.255.)
val width = 300.dp
val squareSize = 60.dp
val swipeableState = rememberSwipeableState(0)
val sizePx = with(LocalDensity.current) { squareSize.toPx() }
val anchors = mapOf(
0f to 0,
sizePx to 1,
sizePx * 2 to 2,
sizePx * 3 to 3,
sizePx * 4 to 4
) // Maps anchor points (in px) to states
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Row(
Modifier
.width(width)
.height(squareSize)) {
repeat(5) {
Box(
Modifier
.width(squareSize)
.fillMaxHeight()
.background(color = Color(list.random(), list.random(), list.random()))
)
}
}
Box(
modifier = Modifier
.width(width)
.swipeable(
state = swipeableState,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.3 f)}, orientation = Orientation.Horizontal ) ) { Box( Modifier .offset { IntOffset(swipeableState.offset.value.roundToInt(),0) }
.width(squareSize)
.height(200.dp)
.background(Color.Yellow)
){
Text(text = "Slide slider")}}}Copy the code
instructions
This is an experimental code
The key code here is as follows: This anchors separates the parent container into five sections, and when the slide ends, the slide control automatically pans to the appropriate area.
val anchors = mapOf(
0f to 0,
sizePx to 1,
sizePx * 2 to 2,
sizePx * 3 to 3,
sizePx * 4 to 4
)
Copy the code
The effect
Two-finger gestures (pan, zoom, rotate)
code
var scale by remember { mutableStateOf(1f)}var rotation by remember { mutableStateOf(0f)}var offset by remember { mutableStateOf(Offset.Zero) }
val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
scale *= zoomChange
rotation += rotationChange
offset += offsetChange
}
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Box(
Modifier
// apply other transformations like rotation and zoom
// on the pizza slice emoji
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation,
translationX = offset.x,
translationY = offset.y
)
// add transformable to listen to multitouch transformation events
// after offset
.transformable(state = state)
.background(Color.Green)
.fillMaxSize(0.5 f),
contentAlignment = Alignment.Center
){
Text(text = "Two-finger manipulation, translation, scaling, Z-rotation, one-finger manipulation will not work.", color = Color.White)
}
}
Copy the code
instructions
The effect
Nested slide effects
code
val toolbarHeight = 48.dp/ / Topbar height
val toolbarHeightPx = with(LocalDensity.current) { toolbarHeight.roundToPx().toFloat() }// Convert topbar height to px
val toolbarOffsetHeightPx =
remember { mutableStateOf(0f)}// Dynamic vertical translation distance of topbar
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
val newOffset = toolbarOffsetHeightPx.value + delta// Update topbar's dynamic translation distance
toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)// Keep the translation distance of topbar between (-toolbarheightpx, 0f)
return Offset.Zero
}
}
}
Box(
Modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection)
) {
LazyColumn(contentPadding = PaddingValues(top = toolbarHeight)) {
items(100) { index ->
Text("I'm item $index", modifier = Modifier
.fillMaxWidth()
.padding(16.dp))
}
}
TopAppBar(
modifier = Modifier
.height(toolbarHeight)
.offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) },
title = { Text("toolbar offset is ${toolbarOffsetHeightPx.value}")})}Copy the code
instructions
The effect
Git address: github.com/ananananzhu…