美文网首页属性动画,自定义属性动画
Android 自定义属性实现3D翻转动效

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

作者: enjoy_coding | 来源:发表于2019-04-15 17:49 被阅读0次

    上一篇文章介绍了属性动画以及如何自定义属性动画,如果关于自定义属性动画你还存在疑问请回去查看上一篇: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()对角度进行控制,以达到翻转的效果。

    相关文章

      网友评论

        本文标题:Android 自定义属性实现3D翻转动效

        本文链接:https://www.haomeiwen.com/subject/lfdpwqtx.html