본문으로 바로가기

[Jetpack Compose] Drag / Swipe /Tap 기능 넣기

category Android_app 2023. 7. 26. 14:04

: 이번에는 핑거  Drag / Swipe /Tap 기능을 한번 사용해 봤습니다.

 

▶ Drag

  : Drag를 적용하기 위해서는 Modifier 의  draggable 또는 pointerInput 를 사용합니다.

 → horizontal Drag

Box(modifier = Modifier.fillMaxSize()){
    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!"
    )
}

 

 

 → Vertical Drag

Box(modifier = Modifier.fillMaxSize()){
    var offsetY by remember { mutableStateOf(0f) }
    Text(
        modifier = Modifier
            .offset { IntOffset(10,offsetY.roundToInt()) }
            .draggable(
                orientation = Orientation.Vertical,
                state = rememberDraggableState { delta ->
                    offsetY += delta
                }
            ),
        text = "Drag me!"
    )
}

 

 

 

 

 → Whole Drag

Box(modifier = Modifier.fillMaxSize()){
    var offsetX by remember { mutableStateOf(0f) }
    var offsetY by remember { mutableStateOf(0f) }
    Box(modifier = Modifier
        .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
        .background(color= Color.Blue)
        .size(50.dp)
        .pointerInput(Unit) {
            detectDragGestures { change, dragAmount ->
                change.consume()
                offsetX += dragAmount.x
                offsetY += dragAmount.y
            }
        },
    ){ ...}
}

 

 

 

 

Swipe  Left/Right

   : X축 기준 500 이상 swipe 시 화면에 Toast 메시지를 띄워 봤습니다.

    Modifier 인자 pointerInput  를 사용해 구현했습니다. 

var direction by remember { mutableStateOf(-1)}
var offsetX by remember { mutableStateOf(0f) }
Box(modifier = Modifier
    .fillMaxSize()
    .background(color = Color.LightGray)
    .pointerInput(Unit) {
        detectDragGestures(
            onDrag = { change, dragAmount ->
                change.consume()
                val (x, y) = dragAmount
                if (abs(x) > abs(y)) {
                    when {
                        x > 0 -> {	//right
                            offsetX += x
                            Log.d(TAG,"offsetX($offsetX)")
                            direction = 0
                        }
                        x < 0 -> {  // left
                            offsetX += x
                            Log.d(TAG,"offsetX($offsetX)")
                            direction = 1
                        }
                    }
                }
            },
            onDragEnd = {
                when (direction) {
                    0 -> {
                        if(offsetX > 500 ) {
                            Toast.makeText(this@NusTestActivity,"Swipe right",Toast.LENGTH_SHORT).show()
                        }
                        offsetX =0f
                    }
                    1 -> {
                        if(offsetX < -500 ) {
                            Toast.makeText(this@NusTestActivity,"Swipe left",Toast.LENGTH_SHORT).show()
                        }
                        offsetX =0f
                    }
                }
            }
        )
    }
){
    Box(modifier = Modifier
        .size(200.dp)
        .background(color = Color.Magenta)
        .align(Alignment.Center)
        .padding(5.dp)
    ){
        Image(
            painter = painterResource(id = R.drawable.arrow_up),
            contentDescription = null,
            modifier = Modifier
                .align(Alignment.TopCenter)
                .size(60.dp)
        )
       ~~ 중략 ~~

    }

}

 

 

 

 

▶ Tap  기능

.pointerInput(Unit){
    detectTapGestures(
        onTap = {
            Offset -> Log.d(TAG,"Tap detected (${Offset.x} ,${Offset.y}")
        },
        onDoubleTap = {
                Offset -> Log.d(TAG,"DoubleTap detected (${Offset.x} ,${Offset.y}")
        }
    )
}

  : Tap 기능과 drag 기능 동시 사용하기

modifier = Modifier
    ~~ 중략 ~~
    .pointerInput(Unit) {
        detectDragGestures(
            onDrag ={ change, dragAmount ->
                change.consume()
                Log.d(TAG, "onDrag 6")
            },
            onDragEnd = {
                Log.d(TAG, "onDragEnd")
            }
        )
    }
    .pointerInput(Unit){
        detectTapGestures(
            onTap = {
                Offset -> Log.d(TAG,"Tap detected (${Offset.x} ,${Offset.y}")
            },
            onDoubleTap = {
                    Offset -> Log.d(TAG,"DoubleTap detected (${Offset.x} ,${Offset.y}")
            }
        )
    }

 

< 기타 >

  Box () compose  안에 Box()를 넣고 양쪽에  Modifer > pointerInput >

    dectectDragGestures  설정시  내부 Box() 만 동작합니다.

Box(modifier = Modifier
    .fillMaxSize()
    .background(color = Color.Cyan)
    .pointerInput(Unit) {
        detectDragGestures(                  <-- 요거 동작안함.
            onDrag = { change, dragAmount ->
                change.consume()
                val (x, y) = dragAmount
                if (abs(x) > abs(y)) {
                    when {
                        x > 0 -> {          //right
                            Log.d(TAG, "offsetX($offsetX)")
                        }
                        x < 0 -> {      // left
                            Log.d(TAG, "offsetX($offsetX)")
                        }
                    }
                }
            },
            ~~ 중략 ~~
        )
    }
)
{
    Box(modifier = Modifier
        .size(200.dp)
        .background(color = Color.Blue)
        .align(Alignment.Center)
        .pointerInput(Unit) {
            detectDragGestures {     <------ 요기 동작함.
                change, dragAmount ->
                change.consume()
            }
        },
    ) {

    }
}

  내부 Box() Compose의 dectectDragGestures  주석처리시 상위의 dectectDragGestures  가 동작합니다.

 

간단히 drag/swipe/ Tap 기능을 사용해 봤습니다.

참고하세요.

 

 

 

반응형