仿美团、饿了么加入购物车动画效果

首先美团的效果:

5wqu1-84ukg.gif

这个动画效果类似于抛物线,对自定义控件不熟悉的同学可能就会有点懵逼,不知道该怎么解决运行轨迹。其实这个抛物线可以用贝塞尔二阶曲线来解决,选择好开始点、控制点和结束点之后,就可以使用二阶曲线方程式来得到小圆点的运行估计x,y坐标。

下面说一下效果的实现步骤:

1.点击+1之后,在布局上添加一个小圆点View
2.获取开始点和结束点的位置信息,选取一个控制点位置。

注意:获取起始位置xy的数据可以使用getLocationInWindow() 或者getLocationOnScreen()方法。两者的区别是:getLocationInWindow()获取的是当前view相对于窗口的位置,getLocationOnScreen()获取的是当前view相对于屏幕的位置.所以如果是在activity中操作两者没什么区别,如果是在dialog中,两者就会区别了。
我使用的是getLocationInWindow()方法,获取到的位置为相对于acitivty的xy坐标,而view的setX()和setY()方法数据都是相对于父布局的,所以,在获取到数据后,需要减去父布局的位置。
如图:


仿美团、饿了么加入购物车动画效果_第1张图片
image.png

3.给第一步添加的view设置一个属性动画(值动画),我们需要重写他的插值器,来设置xy的变化趋势。

大体思路就是这样子的,我实现的效果:

效果:

5au6t-xz7s1.gif

关键代码:

计算起始位置,选择控制点,设置动画

                    //购物车位置
                    var endPoint = IntArray(2)
                    tv_point.getLocationInWindow(endPoint)
                    //按钮位置
                    var startPoint = IntArray(2)
                    view.getLocationInWindow(startPoint)
                    //recyclerview根布局位置
                    var rootPoint = IntArray(2)
                    root_view.getLocationInWindow(rootPoint)

                    //设置红点
                    val img = ImageView(baseContext)
                    img.setImageResource(R.mipmap.icon_cricle_anim)
                    root_view.addView(img)
                    //设置控制点位置
                    val controlPoint = Point(endPoint[0] - rootPoint[0], startPoint[1] - rootPoint[1])
                    //开始位置
                    val start = Point(startPoint[0] - rootPoint[0], startPoint[1] - rootPoint[1])
                    //结束位置
                    val end = Point(endPoint[0] - rootPoint[0], endPoint[1] - rootPoint[1])
                    //启动属性动画
                    val animator = ObjectAnimator.ofObject(img, "point", PointEvaluator(controlPoint), start, end)
                    animator.duration = 1000
                    animator.addListener(this@MainActivity)
                    animator.addUpdateListener { animation ->
                        var point = animation.animatedValue as Point
                        img.x = point.x.toFloat()
                        img.y = point.y.toFloat()
                    }
                    animator.start()

插值器代码:

class PointEvaluator(private var point: Point) : TypeEvaluator {

        //值动画插值器
        override fun evaluate(t: Float, startValue: Point, endValue: Point): Point {

            //贝塞尔二阶函数
            val x = (Math.pow((1 - t).toDouble(), 2.0) * startValue.x + 2 * (1 - t) * t * point.x + Math.pow(t.toDouble(), 2.0) * endValue.x).toInt()
            val y = (Math.pow((1 - t).toDouble(), 2.0) * startValue.y + 2 * (1 - t) * t * point.y + Math.pow(t.toDouble(), 2.0) * endValue.y).toInt()

            return Point(x, y)
        }

    }

源码地址:https://download.csdn.net/download/wangwasdf/10859473

你可能感兴趣的:(仿美团、饿了么加入购物车动画效果)