属性动画,自定义属性动画

Android 自定义属性实现3D翻转动效

2019-04-15  本文已影响0人  enjoy_coding

上一篇文章介绍了属性动画以及如何自定义属性动画,如果关于自定义属性动画你还存在疑问请回去查看上一篇:Android属性动画

那么接下来我们就介绍如果通过自定义属性来实现3D翻转动画效果,首先看效果,效果有点low,大家不要吐槽,主要是要掌握其中的精髓。效果如下:


1555320828962.gif

首先上代码:

class ThreeDRotateView : ViewGroup {
    private val mCamera = Camera()
    private val mMatrix = Matrix()
    private var changeAngle = 0F

    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 onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        measureChildren(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            child.layout(
                0, 0,
                child.measuredWidth,
                child.measuredHeight
            )
        }
    }

    override fun dispatchDraw(canvas: Canvas?) {
        for (i in 0 until childCount) {
            drawScreen(canvas, i, drawingTime)
        }
    }

    private fun drawScreen(canvas: Canvas?, i: Int, drawingTime: Long) {
        val centerX = (width / 2).toFloat()
        val centerY = height.toFloat() / 2
        if (canvas != null) {
            if (changeAngle >= 90F && i == 1) {
            } else {
                drawView(canvas, i, centerX, centerY, drawingTime)
            }
        }
    }

    private fun drawView(canvas: Canvas, i: Int, centerX: Float, centerY: Float, drawingTime: Long) {
        canvas.save()
        mCamera.save()
        mCamera.rotateY(180F * (i + 1) + changeAngle)
        mCamera.getMatrix(mMatrix)
        mCamera.restore()
        mMatrix.preTranslate(-centerX, -centerY)
        mMatrix.postTranslate(centerX, centerY)
        canvas.concat(mMatrix)
        val view = getChildAt(i)
        drawChild(canvas, view, drawingTime)
        canvas.restore()
    }


    fun setChangeAngle(changeAngle: Float) {
        this.changeAngle = changeAngle
        invalidate()
    }

    fun getChangeAngle(): Float {
        return changeAngle
    }
}

布局代码如下:

<com.enhance.kmf.democustomview.view.ThreeDRotateView
            android:layout_width="match_parent"
            android:id="@+id/tdrvContent"
            android:layout_marginTop="50dp"
            android:layout_height="wrap_content">

        <RelativeLayout android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/color_ff5283cc">

            <ImageView android:layout_width="150dp"
                       android:layout_height="150dp"
                       android:layout_centerHorizontal="true"
                       android:background="@drawable/vector_play"/>

            <TextView android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text="Android 自定义属性实现3D翻转动效"
                      android:textSize="28sp"
                      android:layout_marginStart="16dp"
                      android:layout_marginEnd="16dp"
                      android:layout_marginTop="170dp"
                      android:layout_centerInParent="true"
                      android:textColor="@color/color_ffffffff"/>
        </RelativeLayout>

        <RelativeLayout android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@color/color_ff119caa"
        >
            <ImageView android:layout_width="150dp"
                       android:layout_height="150dp"
                       android:layout_centerHorizontal="true"
                       android:background="@drawable/vector_pause"/>
            <TextView android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text=" Android 自定义属性实现3D翻转动效"
                      android:textSize="28sp"
                      android:layout_marginStart="16dp"
                      android:layout_marginEnd="16dp"
                      android:layout_marginTop="170dp"
                      android:layout_centerInParent="true"
                      android:textColor="@color/color_ffffffff"
            />
        </RelativeLayout>
    </com.enhance.kmf.democustomview.view.ThreeDRotateView>

调用代码如下:

 ObjectAnimator.ofFloat(具体控件, "changeAngle", 0F, 180F).apply {
                duration = 1000
                start()
            }

看过上一篇文章的读者应该会对这个套路比较熟悉,还是那三点

  1. 首先我们需要根据需求自定义出相应的动画属性;
  2. 给我们的属性设置相应的get()和set()注意set()方法需要调用invalidate(),
  3. 我们就按照平常的属性动画就能操作自定义的动画了。
    只不过这次是重写的ViewGroup,通过角度判断看是否需要绘制区域来达到动画翻转的效果,角度不够的时候就不绘制该区域的view,只有达到条件才绘制相关view。

具体思路就是通过重写ViewGroup的dispatchDraw()方法,对子view的绘制过程进行控制,然后调用Camera的rotateY()对角度进行控制,以达到翻转的效果。

上一篇下一篇

猜你喜欢

热点阅读