Android 指北针

继承UICompassView实现指北针效果,传感器获取角度之后传入setAngle(angle: Float)

/**
 * JiangMingJie 2020/6/24
 */

import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.SurfaceHolder
import android.view.SurfaceView

/**
 * 指北罗盘的旋转
 */
abstract class UICompassView : SurfaceView, SurfaceHolder.Callback, Runnable {
    /**
     * 设置角度
     */
    private var angle = 0F

    /**
     * 旋转系数 越大越快
     */
    private var moveSpeed = 0.1F

    private var isDraw = true
    private var oldAngle = 0F


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

    init {
        holder.addCallback(this)
    }

    /**
     * 设置当前角度
     */
    fun setAngle(angle: Float) {
        this.angle = angle
    }

    /**
     * 设置旋转速度
     */
    fun setMoveSpeed(moveSpeed: Float) {
        this.moveSpeed = moveSpeed
    }

    private fun pointNorth(canvas: Canvas) {
        if (oldAngle < angle) {
            /**
             * 这里说明角度是突然从0到360
             */
            if (angle - oldAngle > 270) {
                //计算angel -> 0 - oldAngle三个点的总角度
                var total = 360 - angle + oldAngle
                //平滑旋转过去
                oldAngle -= (total) * moveSpeed
                //平滑的旋转过程中如果小于0了 就让它等于360 实现平滑过渡
                if (oldAngle <= 0F) {
                    oldAngle = 360F
                }

            } else {
                oldAngle += (angle - oldAngle) * moveSpeed
            }

        } else if (oldAngle > angle) {
            /**
             * 这里说明角度是突然从360到0
             */
            if (angle - oldAngle < -270) {
                //计算oldAngel -> 0 - angle三个点的总角度
                var total = 360 - oldAngle + angle
                //慢慢旋转过去
                oldAngle += total * moveSpeed
                //平滑的旋转过程中如果大于360了 就让它等于0 实现平滑过渡
                if (oldAngle >= 360F) {
                    oldAngle = 0F
                }
            } else {
                oldAngle -= (oldAngle - angle) * moveSpeed
            }
        }
        canvas.rotate(-oldAngle, width / 2F, height / 2F)
    }

    abstract fun drawUi(canvas: Canvas)
    abstract fun windowChange(width: Int, height: Int)

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
        windowChange(width, height)
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
        isDraw = false
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {
        isDraw = true
        Thread(this).start()
    }

    override fun run() {
        while (isDraw) {
            val canvas = holder.lockCanvas()
            try {
                pointNorth(canvas)
                drawUi(canvas)
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                if (canvas != null) {
                    holder.unlockCanvasAndPost(canvas)
                }
            }
        }
    }

}

你可能感兴趣的:(Android 指北针)