自定义View(初)调用Camera旋转图片

107 阅读2分钟

1635316403321.gif `

package com.example.custom1019.test1027

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import com.example.custom1019.R

class DYCamView : View {
    private var mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var bitmap = BitmapFactory.decodeResource(resources, R.mipmap.maps)
    private var degree = 0
    private var point1 = Point(100, 100)
    private var point2 = Point(point1.x + bitmap.width + 100, 100)

    // TODO 这里面的第二个参数propertyName具体举的是要在当前类有一个方法,
    //  这个方法的名称需要是set开头然后后面是propertyName你填写参数的驼峰式命名,
    //  就像如果你写了 degree ,下面就需要有一个带Int参数的set方法  setDegree(degree:Int)
    //  The object property that you are animating must have a setter function (in camel case) in the form of set().
    //  Because the ObjectAnimator automatically updates the property during animation,
    //  it must be able to access the property with this setter method. For example,
    //  if the property name is foo, you need to have a setFoo() method.
    private var valueAnimator = ObjectAnimator.ofInt(this, "degree", 0, 360).also {
        it.duration = 5000
        it.repeatCount = Animation.INFINITE
        it.interpolator = LinearInterpolator()
    }
    private var camera: Camera = Camera()

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        valueAnimator.start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        valueAnimator.end()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //TODO 关于轴心的设置其实就是把图片的中心点往坐标原点上移动,
        // 而且要反着写代码,就是移动的代码要写在旋转并且应用到Canvas的代码后面,
        // 然后把坐标系移动回去的代码要写在旋转之前(具体原因我看博客也没看懂,好像是之前的操作都是对着坐标系操作,所以才按这样的顺序)
        // Tips:不设置轴心的话出现的View会是斜着的,因为如果没有设置轴心的话Camera是沿着X轴或者Y轴去旋转的,
        // 并且Camera坐标系是3维的,所以沿着X或Y轴旋转出现的View会是斜着的View
        canvas?.save()
        camera.save()
        canvas?.translate(
            (point1.x.toFloat() + bitmap.width / 2),
            (point1.y.toFloat() + bitmap.height / 2)
        )
        camera.rotateX(degree.toFloat())
        camera.applyToCanvas(canvas)
        canvas?.translate(
            -(point1.x.toFloat() + bitmap.width / 2),
            -(point1.y.toFloat() + bitmap.height / 2)
        )
        camera.restore()
        canvas?.drawBitmap(bitmap, point1.x.toFloat(), point1.y.toFloat(), mPaint)
        canvas?.restore()
        // 二
        canvas?.save()
        camera.save()
        canvas?.translate(
            (point2.x + bitmap.width / 2).toFloat(),
            (point2.y + bitmap.height / 2).toFloat()
        )
        camera.rotateY(degree.toFloat())
        camera.applyToCanvas(canvas)
        canvas?.translate(
            -(point2.x + bitmap.width / 2).toFloat(),
            -(point2.y + bitmap.height / 2).toFloat()
        )

        canvas?.drawBitmap(bitmap, point2.x.toFloat(), point2.y.toFloat(), mPaint)
        camera.restore()
        canvas?.restore()
    }

    fun setDegree(degree: Int) {
        this.degree = degree
        invalidate()
    }
}

`