티스토리 뷰

SWDesk/App

[Android] ImageView Event Treatment

bizmaker 2024. 6. 18. 19:30

이미지뷰 이벤트 처리_240618.docx
0.05MB

 

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var imageView1: ImageView
    private lateinit var imageView2: ImageView
    private lateinit var imageView3: ImageView

    private var startX: Float = 0f
    private var startY: Float = 0f
    private var isLongPressed = false
    private var isDraggingValid = true
    private var initialViewId: Int = 0

    private val handler = Handler(Looper.getMainLooper())
    private val longPressRunnable = Runnable {
        isLongPressed = true
        Log.d("TouchEvent", "Long Press detected at: ($startX, $startY)")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        imageView1 = findViewById(R.id.imageView1)
        imageView2 = findViewById(R.id.imageView2)
        imageView3 = findViewById(R.id.imageView3)

        imageView1.setOnTouchListener(touchListener)
        imageView2.setOnTouchListener(touchListener)
        imageView3.setOnTouchListener(touchListener)
    }

    private val touchListener = View.OnTouchListener { view, event ->
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                // 손가락을 눌렀을 때
                startX = event.x
                startY = event.y
                isLongPressed = false
                isDraggingValid = true
                initialViewId = view.id
                handler.postDelayed(longPressRunnable, 500) // 0.5초 이후 longPressRunnable 실행
                Log.d("TouchEvent", "Pressed at: ($startX, $startY) on view ${view.id}")
                true
            }
            MotionEvent.ACTION_UP -> {
                // 손가락을 뗐을 때
                handler.removeCallbacks(longPressRunnable)
                if (isDraggingValid && !isLongPressed) {
                    val endX = event.x
                    val endY = event.y
                    Log.d("TouchEvent", "Released at: ($endX, $endY) on view ${view.id}")
                    val direction = getDragDirection(startX, startY, endX, endY)
                    Log.d("TouchEvent", "Drag Direction: $direction on view ${view.id}")
                }
                true
            }
            MotionEvent.ACTION_MOVE -> {
                // 손가락을 움직일 때
                if (isLongPressed) {
                    // 길게 눌렀을 때는 움직임을 무시하거나 다른 동작을 수행할 수 있습니다.
                    handler.removeCallbacks(longPressRunnable)
                } else if (isDraggingValid) {
                    val currentX = event.x
                    val currentY = event.y

                    // 현재 위치가 이미지뷰의 경계를 벗어나는지 확인
                    if (!isPointInsideView(currentX, currentY, view)) {
                        isDraggingValid = false
                        Log.d("TouchEvent", "Dragging outside of view ${view.id}, invalidating drag")
                    } else {
                        Log.d("TouchEvent", "Dragged to: ($currentX, $currentY) on view ${view.id}")
                        checkDragToOtherViews(currentX, currentY, view)
                    }
                }
                true
            }
            MotionEvent.ACTION_CANCEL -> {
                // 터치 이벤트가 취소될 때
                handler.removeCallbacks(longPressRunnable)
                true
            }
            else -> false
        }
    }

    private fun isPointInsideView(x: Float, y: Float, view: View): Boolean {
        return x >= 0 && x <= view.width && y >= 0 && y <= view.height
    }

    private fun getDragDirection(startX: Float, startY: Float, endX: Float, endY: Float): String {
        val deltaX = endX - startX
        val deltaY = endY - startY

        return when {
            Math.abs(deltaX) > Math.abs(deltaY) -> {
                if (deltaX > 0) "Right" else "Left"
            }
            else -> {
                if (deltaY > 0) "Down" else "Up"
            }
        }
    }

    private fun checkDragToOtherViews(x: Float, y: Float, currentView: View) {
        // 이미지뷰 1에서 시작한 드래그가 이미지뷰 2 또는 3으로 이동하는지 확인
        when (currentView.id) {
            R.id.imageView1 -> {
                if (isPointInsideViewRelativeToOtherView(x, y, imageView2)) {
                    Log.d("TouchEvent", "Dragged to imageView2 from imageView1")
                } else if (isPointInsideViewRelativeToOtherView(x, y, imageView3)) {
                    Log.d("TouchEvent", "Dragged to imageView3 from imageView1")
                }
            }
            R.id.imageView2 -> {
                if (isPointInsideViewRelativeToOtherView(x, y, imageView1)) {
                    Log.d("TouchEvent", "Dragged to imageView1 from imageView2")
                } else if (isPointInsideViewRelativeToOtherView(x, y, imageView3)) {
                    Log.d("TouchEvent", "Dragged to imageView3 from imageView2")
                }
            }
            R.id.imageView3 -> {
                if (isPointInsideViewRelativeToOtherView(x, y, imageView1)) {
                    Log.d("TouchEvent", "Dragged to imageView1 from imageView3")
                } else if (isPointInsideViewRelativeToOtherView(x, y, imageView2)) {
                    Log.d("TouchEvent", "Dragged to imageView2 from imageView3")
                }
            }
        }
    }

    private fun isPointInsideViewRelativeToOtherView(x: Float, y: Float, otherView: View): Boolean {
        val location = IntArray(2)
        otherView.getLocationOnScreen(location)
        val viewX = location[0]
        val viewY = location[1]
        return x >= viewX && x <= viewX + otherView.width && y >= viewY && y <= viewY + otherView.height
    }
}

 

반응형

'SWDesk > App' 카테고리의 다른 글

안드로이드앱에서 광고 및 결제를 관리하기 위한 예제 코드  (2) 2025.01.18
[Kotlin] Treat Key Event  (0) 2024.06.14
[Android] Fragment 개념  (1) 2024.04.08
[Android] 그래프 예제  (2) 2024.04.06
[Android] RecyclerView 예제  (0) 2024.04.04