iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0

Compose 的手勢 Gestures

 在Compose 的手勢  提供很多可以偵測到手勢來產生互動	 
- 輕觸並按下 clickable
- 捲動
  1. 捲動輔助鍵
  2. 可捲動的輔助鍵
- 巢狀捲動
- 拖曳
- 滑動
- 多點觸控:平移、縮放、旋轉  

輕觸並按下 clickable

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

https://ithelp.ithome.com.tw/upload/images/20220929/20121643WBOBMWur8g.png

捲動

注意:如要顯示項目清單,建議使用 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))
        }
    }
}

https://ithelp.ithome.com.tw/upload/images/20220929/2012164334q02Cl4Qq.png

可捲動的輔助鍵

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

https://ithelp.ithome.com.tw/upload/images/20220929/20121643BMe6xHzyeP.png

巢狀捲動

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

https://ithelp.ithome.com.tw/upload/images/20220929/20121643Ur9zSvWOmj.png

拖曳

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

https://ithelp.ithome.com.tw/upload/images/20220929/20121643O3ebRG93Fp.png

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

https://ithelp.ithome.com.tw/upload/images/20220929/20121643TSviAAIv7g.png

滑動

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

https://ithelp.ithome.com.tw/upload/images/20220930/20121643FluqrfztmE.png

多點觸控:平移、縮放、旋轉

如要偵測用來平移、縮放及旋轉的多點觸控手勢,您可以使用 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://ithelp.ithome.com.tw/upload/images/20220929/20121643k9MX9CjIAn.png

參考:

https://developer.android.com/jetpack/compose/gestures


上一篇
寫Jetpack Compose ,會很有畫面哦! - Day22 Compose 的動畫 Animation High-level
下一篇
寫Jetpack Compose ,會很有畫面哦! - Day24 Compose 的導覽元件 Navigation
系列文
寫Jetpack Compose ,會很有畫面哦!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言