Android(安卓)kotlin 自定义View 旋转、移动、放缩 ImageView
16lz
2022-07-30
0、效果图
1、功能
功能:
放缩:三指操作
旋转:两只操作
移动:单指操作
2、实现代码
import android.content.Contextimport android.graphics.Matriximport android.graphics.PointFimport android.util.AttributeSetimport android.util.Logimport android.view.MotionEventimport android.view.ScaleGestureDetectorimport kotlin.math.atanclass RotateZoomImageView(context: Context, attrs: AttributeSet?) : androidx.appcompat.widget.AppCompatImageView(context, attrs) { private val TAG = "RotateZoomImageView" private var mScaleGestureDetector: ScaleGestureDetector private var mImageMatrix: Matrix = Matrix() private val savedMatrix: Matrix = Matrix() private var x = 0 private var y = 0 private var mLastAngle = 0 // 第一个按下的手指的点 private val startPoint = PointF() private val mScaleListener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() { override fun onScale(detector: ScaleGestureDetector): Boolean { //缩放比例因子 val scaleFactor = detector.scaleFactor mImageMatrix.postScale(scaleFactor, scaleFactor, x.toFloat(), y.toFloat()) imageMatrix = mImageMatrix return true } } init { mScaleGestureDetector = ScaleGestureDetector(context, mScaleListener) scaleType = ScaleType.MATRIX } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { if (w != oldw || h != oldh) { val transX = (w - drawable.intrinsicWidth) / 2.0 val transY = (h - drawable.intrinsicHeight) / 2.0 mImageMatrix.setTranslate(transX.toFloat(), transY.toFloat()) imageMatrix = mImageMatrix x = w / 2 y = h / 2 } } private fun doRotationEvent(ev: MotionEvent): Boolean { //计算两个手指的角度 val dx = ev.getX(0) - ev.getX(1) val dy = ev.getY(0) - ev.getY(1) //弧度 val radians = atan(dy.toDouble() / dx.toDouble()) //角度 val degrees = (radians * 180 / Math.PI).toInt() when (ev.actionMasked) { MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_POINTER_UP -> mLastAngle = degrees MotionEvent.ACTION_MOVE -> { when { (degrees - mLastAngle) > 45 -> mImageMatrix.postRotate( -5f, x.toFloat(), y.toFloat() ) (degrees - mLastAngle) < -45 -> mImageMatrix.postRotate( 5f, x.toFloat(), y.toFloat() ) else -> mImageMatrix.postRotate( (degrees - mLastAngle).toFloat(), x.toFloat(), y.toFloat() ) } imageMatrix = mImageMatrix mLastAngle = degrees } } return true } private fun doMoveEvent(ev: MotionEvent): Boolean { when (ev.actionMasked) { MotionEvent.ACTION_MOVE -> { mImageMatrix.set(savedMatrix) mImageMatrix.postTranslate(ev.x - startPoint.x, ev.y - startPoint.y) imageMatrix = mImageMatrix } } return true } override fun onTouchEvent(event: MotionEvent): Boolean { if (event.action == MotionEvent.ACTION_DOWN) { Log.d("drag", "onTouch: x= ${event.rawX.toInt()},y=${event.rawY.toInt()}" ) mImageMatrix.set(imageMatrix) savedMatrix.set(mImageMatrix) startPoint[event.x] = event.y return true } return when (event.pointerCount) { 3 -> mScaleGestureDetector.onTouchEvent(event) 2 -> doRotationEvent(event) 1 -> doMoveEvent(event) else -> super.onTouchEvent(event) } }}
3、布局引用
<?xml version="1.0" encoding="utf-8"?>
更多相关文章
- Android下Excel的操作
- 【Android】文件读写操作(含SDCard的读写)
- android中MotionEvent.ACTION_CANCEL事件如何被触发?
- 自定义带倒影和偏转的超炫Gallery
- android 百度地图3.0+常用操作
- Android(安卓)重力感应获取手机运动方向和角度
- 转:Android下文件操作模式(含SDCard的读写)
- android音频、视频、拍照基础操作
- Android之再谈文件操作和SDcard读写