Kotlin : ImageView 이미지 확대, 축소, 회전 기능
2023. 2. 2. 20:22ㆍ[Android APP] feat. Kotlin/Kotlin 공부
문제 상황
Image를 ImageView에 띄어준 뒤, 이미지에 있는 작은 글씨를 보기 위해 이미지 확대/축소 기능이 필요했다.
해결
1. TouchMode 등 선언
internal enum class TOUCHMODE {
NONE,
SINGLE,
MULTI
}
private var touchMode: TOUCH_MODE? = null
private var matrix : Matrix? = null
private var savedMatrix : Matrix? = null
private var startPoint: PointF? = null
private var midPoint : PointF? = null
private var oldDistance = 0f
private var oldDegree = 0.0
2. 이미지 확대/축소 실행
matrix = Matrix()
savedMatrix = Matrix()
binding.blueprintImage.setOnTouchListener(onTouch)
binding.blueprintImage.scaleType = ImageView.ScaleType.MATRIX
3. 이미지 확대/축소 함수
@SuppressLint("ClickableViewAccessibility")
private val onTouch = OnTouchListener { v, event ->
if (v == binding.blueprintImage) {
val action = event.action
when (action and MotionEvent.ACTION_MASK) {
//한 손가락 터치
MotionEvent.ACTION_DOWN -> {
touchMode = TOUCH_MODE.SINGLE
donwSingleEvent(event)
}
//두 손가락 터치
MotionEvent.ACTION_POINTER_DOWN -> if (event.pointerCount == 2) {
touchMode = TOUCH_MODE.MULTI
downMultiEvent(event)
}
//한 손가락 이동
MotionEvent.ACTION_MOVE -> if (touchMode === TOUCH_MODE.SINGLE) {
moveSingleEvent(event)
}
//두 손가락 이동
else if (touchMode === TOUCH_MODE.MULTI) {
moveMultiEvent(event)
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> touchMode = TOUCH_MODE.NONE
}
}
true
}
- 두 손가락 간 중간점을 찾아주는 함수
private fun getMidPoint(e: MotionEvent): PointF? {
val x = (e.getX(0) + e.getX(1)) / 2
val y = (e.getY(0) + e.getY(1)) / 2
return PointF(x, y)
}
- 각 손가락 간 거리를 구해주는 함수
private fun getDistance(e: MotionEvent): Float {
val x = e.getX(0) - e.getX(1)
val y = e.getY(0) - e.getY(1)
return Math.sqrt((x * x + y * y).toDouble()).toFloat()
}
- 한손가락, 두 손가락으로 터치했을 때 시작점을 구하는 함수
private fun donwSingleEvent(event: MotionEvent) {
savedMatrix!!.set(matrix)
startPoint = PointF(event.x, event.y)
}
private fun downMultiEvent(event: MotionEvent) {
oldDistance = getDistance(event)
if (oldDistance > 5f) {
savedMatrix!!.set(matrix)
midPoint = getMidPoint(event)
val radian = atan2((event.y - midPoint!!.y).toDouble(), (event.x - midPoint!!.x).toDouble())
oldDegree = radian * 180 / Math.PI
}
}
- 한 손가락, 두 손가락으로 이동 및 회전하는 함수
(본인은 회전하는 기능이 불필요 했기 때문에 degree 대신 0.0.toFloat() 값을 넣어줘서 회전을 막았다.)
private fun moveSingleEvent(event: MotionEvent) {
matrix!!.set(savedMatrix)
matrix!!.postTranslate(event.x - startPoint!!.x, event.y - startPoint!!.y)
binding.blueprintImage.imageMatrix = matrix
}
private fun moveMultiEvent(event: MotionEvent) {
val newDistance = getDistance(event)
if (newDistance > 5f) {
matrix!!.set(savedMatrix)
val scale = newDistance / oldDistance
matrix!!.postScale(scale, scale, midPoint!!.x, midPoint!!.y)
val nowRadian =
Math.atan2((event.y - midPoint!!.y).toDouble(), (event.x - midPoint!!.x).toDouble())
val nowDegress = nowRadian * 180 / Math.PI
val degree = (nowDegress - oldDegree).toFloat()
matrix!!.postRotate(degree, midPoint!!.x, midPoint!!.y)
binding.blueprintImage.imageMatrix = matrix
}
}
반응형
'[Android APP] feat. Kotlin > Kotlin 공부' 카테고리의 다른 글
Kotlin : Lottie Library(애니메이션 적용) (0) | 2023.02.22 |
---|---|
Kotlin : Fragment의 생명주기 (0) | 2023.02.05 |
Kotlin : Thread, Handler (0) | 2023.02.02 |
Android : Kotlin Retrofit 동기 처리 (0) | 2022.11.02 |
Android Kotlin : 안드로이드 Activity 생명 주기 (0) | 2022.10.22 |