Closed3

Modifier修飾子を見る(3)

mtkw0127mtkw0127

Modifier#draggable

単一方向のdrag中の位置情報を取れる。

ユースケース:コンポーネント内の何かをドラッグで移動したい

全方位のdragを考えている場合はpointerInputのdetectDragGesturesを利用する

https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).draggable(androidx.compose.foundation.gestures.DraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Boolean,kotlin.coroutines.SuspendFunction2,kotlin.coroutines.SuspendFunction2,kotlin.Boolean)

サンプルコード

確かに移動した。

val max = 300.dp
val min = 0.dp
val (minPx, maxPx) = with(LocalDensity.current) { min.toPx() to max.toPx() }
val offsetPosition = remember { mutableFloatStateOf(0f) } // [1]現在の位置
Box(
    modifier = Modifier
        .width(max)
        .draggable(
            orientation = Orientation.Horizontal,
            state = rememberDraggableState { delta -> // [2]dragで移動した距離
                val newValue = offsetPosition.value + delta // [3]新しい位置を更新
                offsetPosition.value = newValue.coerceIn(minPx, maxPx)
            }
        )
        .background(Color.Black)
) {
    Box(
        Modifier
            .offset { IntOffset(offsetPosition.value.roundToInt(), 0) }// [4]四角い箱が移動
            .size(50.dp)
            .background(Color.Red)
    )
}

Modifier#pointerInput#detectDragGestures

横にも縦にも動くようなDragはpointerInputを使うということなのでそれも書いてみた。

val size = 300.dp
var offsetPosition by remember { mutableStateOf(IntOffset.Zero) }
Box(
    modifier = Modifier
        .size(size)
        .pointerInput(Unit) {
            detectDragGestures { _, dragAmount ->
                offsetPosition += IntOffset(dragAmount.x.toInt(), dragAmount.y.toInt())
            }
        }
        .background(Color.Black)
) {
    Box(
        Modifier
            .offset { offsetPosition }
            .size(50.dp)
            .background(Color.Red)
    )
}

動いた。

mtkw0127mtkw0127

Modifier#indication

インタラクション(クリック等)が発生した際に、視覚的なエフェクトを表示することができる。

サンプルを動かしてみた。

AをクリックしたときにBにも視覚的なエフェクトが出た。

val interactionSource = remember { MutableInteractionSource() } // [2] インタラクションが検知される
Column {
    Text(
        text = "A", // [1] クリックする
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = rememberRipple()
            ) {}
            .padding(10.dp)
    )
    Spacer(Modifier.requiredHeight(10.dp))
    Text(
        text = "B",
        modifier = Modifier
            .indication(interactionSource, LocalIndication.current) // [3] リップルエフェクトが発生する
            .padding(10.dp)
    )
}
mtkw0127mtkw0127

Modifier#graphicsLayer

https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).graphicsLayer(kotlin.Function1)

  • コンテンツのスケール、角度、不透明度、シャドウ、クリッピンを変化できる
  • アニメーションで変化させてもReCompositionとReLayoutが走らないので良い。
var clicked by remember { mutableStateOf(false) }
val animatedRotation =
    animateFloatAsState(
        targetValue = if (clicked) 360f else 0f,
        tween(),
        label = "TextRotationAnimation"
    )
SideEffect {
    Log.d("@@@", "${animatedRotation.value}")
}
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
    Text(
        "Hello World",
        Modifier
            .graphicsLayer {
                rotationX = animatedRotation.value
                rotationY = animatedRotation.value
                rotationZ = animatedRotation.value
            }
            .clickable {
                clicked = clicked.not()
            }
    )
}
このスクラップは2023/10/02にクローズされました