自定义 View 实战 05 - 仿 58 加载View

2020-06-28 15:48:22 浏览数 (2)

view58.gif

动画分析:

  • 圆形
  • 正方形
  • 三角形

分别使用drawCircle()drawRect()drawPath(),画出对应的图形,然后使用属性动画让它移动和旋转。

代码语言:javascript复制
class View58 @JvmOverloads constructor(context: Context,attributeSet: AttributeSet,defStyle:Int = 0):View(context,attributeSet,defStyle) {

    private var mPaint = Paint()
    private var mZColor = Color.BLUE
    private var mSColor = Color.GRAY
    private var mC = Color.RED
    private var mType = DrawType.y
    private var mRect = Rect()
    private var mPath = Path()
    private var mDuration = 800L
    private var mStokeWidth = dp2Px(2,context.resources).toFloat()


    init {
        mPaint.isAntiAlias = true
        mPaint.style = Paint.Style.STROKE
        mPaint.strokeWidth = mStokeWidth
        mPaint.strokeCap = Paint.Cap.BUTT
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //这里需要使用 measureWidth 和 measureHeight , 如果使用 width 和 height 不一定有值
        var widthSize = measuredWidth
        var heightSize = measuredHeight

        if (widthSize > heightSize) widthSize = heightSize

        if (heightSize > widthSize) heightSize = widthSize

        setMeasuredDimension(widthSize, heightSize)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        when(mType){
            //正方形
            DrawType.z ->{
                mRect.left = 0
                mRect.top = 0
                mRect.right = width
                mRect.bottom = height
                mPaint.color = mZColor
                canvas.drawRect(mRect,mPaint)
            }
            //圆形
            DrawType.y ->{
                mPaint.color = mC
                canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(),
                    (width/2).toFloat()-mStokeWidth,mPaint)
            }
            //三角形
            DrawType.s ->{
                canvas.save()
                canvas.translate((width/2).toFloat(), (height/2).toFloat())
                mPath.moveTo(0f,(-width/2).toFloat())
                mPath.lineTo((width)/2f,0f)
                mPath.lineTo((-width)/2f,0f)
                mPath.close()
                mPaint.color = mSColor
                canvas.drawPath(mPath,mPaint)
                canvas.restore()
            }
        }

    }

    //向上平移动画
    fun startAnim(){
        val objAnim = ObjectAnimator.ofFloat(this,"translationY",0f,-height.toFloat())
        objAnim.duration = mDuration
        objAnim.interpolator = AccelerateInterpolator()
        objAnim.addListener(object :Animator.AnimatorListener{
            override fun onAnimationRepeat(animation: Animator) {
            }

            override fun onAnimationEnd(animation: Animator) {
                down()
            }

            override fun onAnimationCancel(animation: Animator) {
            }

            override fun onAnimationStart(animation: Animator) {
                rotateX()
            }


        })
        objAnim.start()
    }
     //旋转动画
     private fun rotateX(){
         val objAnim = ObjectAnimator.ofFloat(this,"rotation",0f,180f)
         objAnim.duration = mDuration
         objAnim.addListener(object :Animator.AnimatorListener{
             override fun onAnimationRepeat(animation: Animator) {
             }

             override fun onAnimationEnd(animation: Animator) {
             }

             override fun onAnimationCancel(animation: Animator) {
             }

             override fun onAnimationStart(animation: Animator) {
             }


         })
         objAnim.start()
     }
    //下落动画
    private fun down(){
        val objAnim = ObjectAnimator.ofFloat(this,"translationY",-height.toFloat(),0f)
        objAnim.duration = mDuration
        objAnim.interpolator = AccelerateInterpolator()
        objAnim.addListener(object :Animator.AnimatorListener{
            override fun onAnimationRepeat(animation: Animator) {
            }

            override fun onAnimationEnd(animation: Animator) {
                changeType()
                startAnim()
            }

            override fun onAnimationCancel(animation: Animator) {
            }

            override fun onAnimationStart(animation: Animator) {
                rotateX()
            }


        })
        objAnim.start()
    }
    //三个图形不断的切换
    private fun changeType(){
        mType = when (mType) {
            DrawType.y ->{
                DrawType.z
            }
            DrawType.z ->{
                DrawType.s
            }
            DrawType.s ->{
                DrawType.y
            }
        }
        invalidate()
    }

    enum class DrawType{
        //正方形,圆,三角形
        z,y,s
    }
}

项目地址

0 人点赞