Android打造能旋转能缩放的ImageView(Kotlin版)

引言

嗨,好久不见,大家还好么?这回我带来了最新的用kotlin打造的imageview,属于kotlin练手级别小制作,希望大家喜欢~~
先看效果,然后看源码,关键部分已有注释。

采用的是3指缩放,2指旋转。

效果图

在这里插入图片描述
涉及知识点

  • 安卓手势
  • 矩阵
  • assets目录
  • 安卓触摸事件处理
  • 自定义view
  • 一点点的数学运算

kotlin知识点

  • 类的继承
  • 从构造方法
  • object关键字
  • when的使用
  • 如何创建一个对象
  • 懒加载
  • val和var区别
  • 类型转换

不会的小伙伴还要加油哦!kotlin未来可是安卓开发的主流~

自定义view源码

class RotateZoomImageView : ImageView {

    private lateinit var mScaleGestureDetector: ScaleGestureDetector
    private var mLastAngle = 0
    private var x = 0
    private var y = 0
    private lateinit var mImageMatrix: Matrix
    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
        }
    }

    constructor(context: Context): super(context) {
        init(context);
    }

    constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet) {
        init(context);
    }

    constructor(context: Context, attributeSet: AttributeSet, defStyle: Int): super(context, attributeSet, defStyle) {
        init(context);
    }

    private fun init(context: Context) {
        mScaleGestureDetector = ScaleGestureDetector(context, mScaleListener)
        scaleType = ImageView.ScaleType.MATRIX
        mImageMatrix = 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 = Math.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
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            return true
        }
        when (event.pointerCount) {
            3 -> return mScaleGestureDetector.onTouchEvent(event)
            2 -> return doRotationEvent(event)
            else -> return super.onTouchEvent(event)
        }
    }
}

Activity源码

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val iv = RotateZoomImageView(this)

        val inp = assets.open("android.jpg")
        val image = BitmapFactory.decodeStream(inp)
        iv.setImageBitmap(image)

        setContentView(iv)
    }
}

支持我

您的支持,就是我创作的最大动力

发布了28 篇原创文章 · 获赞 49 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qwe25878/article/details/89644191
今日推荐