在Compose 的手勢 提供很多可以偵測到手勢來產生互動
- 輕觸並按下 clickable
- 捲動
1. 捲動輔助鍵
2. 可捲動的輔助鍵
- 巢狀捲動
- 拖曳
- 滑動
- 多點觸控:平移、縮放、旋轉
clickable 輔助鍵可讓應用程式偵測已套用該輔助鍵的元素所獲得的點擊次數
@Composable
fun Greeting(name: String) {
val count = remember { mutableStateOf(0) }
// content that you want to make clickable
Text(
text = count.value.toString(),
modifier = Modifier.clickable { count.value += 1 }
)
}
注意:如要顯示項目清單,建議使用 LazyColumn 和 LazyRow 而不要使用這些 API。LazyColumn 和 LazyRow 具備捲動功能,且使用效率遠高於捲動輔助鍵,因為前兩者只需視需要撰寫項目。詳情請參閱清單和格線文件。
@Composable
fun Greeting(name: String) {
Column(
modifier = Modifier
.background(Color.LightGray)
.size(100.dp)
.verticalScroll(rememberScrollState())
) {
repeat(10) {
Text("Item $it", modifier = Modifier.padding(2.dp))
}
}
}
###Smoothly
@Composable
fun Greeting(name: String) {
// Smoothly scroll 100px on first composition
val state = rememberScrollState()
LaunchedEffect(Unit) { state.animateScrollTo(100) }
Column(
modifier = Modifier
.background(Color.LightGray)
.size(100.dp)
.padding(horizontal = 8.dp)
.verticalScroll(state)
) {
repeat(10) {
Text("Item $it", modifier = Modifier.padding(2.dp))
}
}
}
scrollable 輔助鍵與捲動輔助鍵的差別在於scrollable會偵測捲動手勢,但不會偏移其內容
@Composable
fun Greeting(name: String) {
// actual composable state
var offset by remember { mutableStateOf(0f) }
Box(
Modifier
.size(150.dp)
.scrollable(
orientation = Orientation.Vertical,
// Scrollable state: describes how to consume
// scrolling delta and update offset
state = rememberScrollableState { delta ->
offset += delta
delta
}
)
.background(Color.LightGray),
contentAlignment = Alignment.Center
) {
Text(offset.toString())
}
}
Compose 支援巢狀捲動,讓多個元素回應單一捲動手勢
自動巢狀捲動
@Composable
fun Greeting(name: String) {
val gradient = Brush.verticalGradient(0f to Color.Gray, 1000f to Color.White)
Box(
modifier = Modifier
.background(Color.LightGray)
.verticalScroll(rememberScrollState())
.padding(32.dp)
) {
Column {
repeat(6) {
Box(
modifier = Modifier
.height(128.dp)
.verticalScroll(rememberScrollState())
) {
Text(
"Scroll here",
modifier = Modifier
.border(12.dp, Color.DarkGray)
.background(brush = gradient)
.padding(24.dp)
.height(150.dp)
)
}
}
}
}
}
draggable 修飾符是高階進入點,可讓您循單一方向拖曳手勢,並回報拖曳距離 (以像素為單位)。
@Composable
fun Greeting(name: String) {
var offsetX by remember { mutableStateOf(0f) }
Text(
modifier = Modifier
.offset { IntOffset(offsetX.roundToInt(), 0) }
.draggable(
orientation = Orientation.Horizontal,
state = rememberDraggableState { delta ->
offsetX += delta
}
),
text = "Drag me!"
)
}
@Composable
fun Greeting(name: String) {
Box(modifier = Modifier.fillMaxSize()) {
var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
Box(
Modifier
.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
.background(Color.Blue)
.size(50.dp)
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consumeAllChanges()
offsetX += dragAmount.x
offsetY += dragAmount.y
}
}
)
}
}
swipeable 修飾符可讓您拖曳元素,一旦放開手指時,這些元素通常會朝方向中定義的兩個 (或更多) 錨點建立動畫。
@Composable
fun Greeting(name: String) {
val width = 96.dp
val squareSize = 48.dp
val swipeableState = rememberSwipeableState(0)
val sizePx = with(LocalDensity.current) { squareSize.toPx() }
val anchors = mapOf(0f to 0, sizePx to 1) // Maps anchor points (in px) to states
Box(
modifier = Modifier
.width(width)
.swipeable(
state = swipeableState,
anchors = anchors,
thresh![https://ithelp.ithome.com.tw/upload/images/20220929/20121643sqWzfTDNGe.png](https://ithelp.ithome.com.tw/upload/images/20220929/20121643sqWzfTDNGe.png)olds = { _, _ -> FractionalThreshold(0.3f) },
orientation = Orientation.Horizontal
)
.background(Color.LightGray)
) {
Box(
Modifier
.offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
.size(squareSize)
.background(Color.DarkGray)
)
}}
如要偵測用來平移、縮放及旋轉的多點觸控手勢,您可以使用 transformable 輔助鍵。
@Composable
fun Greeting(name: String) {
// set up all transformation states
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
// 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.Blue)
.fillMaxSize()
)
}
https://developer.android.com/jetpack/compose/gestures