美文网首页实用控件Android开发社区Android_Study
仿美团外卖添加商品的抛物线动画

仿美团外卖添加商品的抛物线动画

作者: iam薛定諤 | 来源:发表于2016-08-30 22:44 被阅读5833次

    GitHub - jlcclidong/AddCartAniamtion: 仿美团外卖添加动画的三方库

    1.初衷

             公司要做一个点餐系统,要求类似要的美团外卖的点餐动画,就像下面这样一个抛物线(biu)

    美团的动画

    身为一个把时间节约全部投入到工作中的程序员,baidu geogle了好久发现没有这个动画效果的具体实现.有的效果也不是很好,只好自己写一个这样的效果了(搬砖去了)


    2.结果

    结果demo就是和下面一样做的一个动画效果

    自己的动画

    可以直接使用拷贝这个类或者在Project中build.gradle添加

    allprojects{
              repositories{
                       ... 
                       maven{url"https://jitpack.io"}
             }
    }

    在Moudle中的build.gradle

    dependencies{
                compile'com.github.jlcclidong:AddCartAniamtion:v3.0'
    }

    直接使用AddCartAniamtion.AddToCart()完成动画,图片默认为填入ImageView的图片,想要自己更改的可以去源码中更改,本人水平有限,希望多交流。

    自己使用在RecycleView中没有问题。动画左右飞都木有问题。

    3.过程

    本身看到过一个用贝塞尔曲线来做这个效果的,效果不好(好吧,主要是自己数学实在不争气)
    身为程序员里物理学的最好的还是用物理公式来解决问题吧,加属性动画

    首先确定父控件,起始位置控件,以及终点位置控件位置


    //计算父控件的位置
    int[] parent =new int[2];
    rl.getLocationInWindow(parent);

    //计算起点控件位置
    int[] startLocation =new int[2];
    startView.getLocationInWindow(startLocation);

    //计算终点控件位置
    int[] endLocation =new int[2];
    endView.getLocationInWindow(endLocation);

    添加一个用于ImageView用于动画(注意确定添加的位置是一定要注意父控件的Padding值,因为这个错位了好久)

    final ImageView view =newImageView(mContext);

    //确定ImageView大小与传进来的ImageView相同
    RelativeLayout.LayoutParams params =new RelativeLayout.LayoutParams(startView.getWidth(),startView.getHeight());

    //获取ImageView的图片 并设置在新的ImageView上
    view.setImageDrawable(startView.getDrawable());

    //确定ImageView的位置与startView相同
    params.leftMargin= startLocation[0] - parent[0] - rl.getPaddingLeft();
    params.topMargin= startLocation[1] - parent[1] - rl.getPaddingTop();

    rl.addView(view,params);

    好吧重点来了 我把初始的X轴Y轴速度设成相同的这样保证了上移的效果 然后根据时间 距离计算初速度 加速度 基本就用到了这么一个公式

    s=vt+g*t*t/2

    //计算两者的横向X轴的距离差
    int XtoX = endLocation[0] - startLocation[0] + endView.getWidth() /2-
                   startView.getWidth() /2;

    //根据距离 时间 获取到对应的X轴的初速度
    final float xv = XtoX / time;

    //计算两者的横向X轴的距离差
    int YtoY = endLocation[1] - startLocation[1];

    //根据距离 时间 初始设置的Y轴初速度与X轴初速度相同 获取到竖直方向上的加速度
    final float g;
    if(xv>0) {

               g = (YtoY + xv * time) / time / time *2;
    }else{
               g = (YtoY - xv * time) / time / time *2;
    }

    设置属性动画了

    ValueAnimator va =new ValueAnimator();
    va.setDuration(time *1000);
    va.setObjectValues(newPointF(0,0));

    //计算位置

    va.setEvaluator(new TypeEvaluator() {
                @Override
                publicPointFevaluate(float v,PointF pointF,PointF t1) {
                              PointF point =newPointF();
                              point.x= v *xv*time;
                              if(xv>0) {
                                   point.y=g* (v *time) * (v *time) /2-xv* v *time;
                              }else{
                                  point.y=g* (v *time) * (v *time) /2+xv* v *time;
                             }
                             return point;
              }
    });

    //设置动画
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                         public void onAnimationUpdate(ValueAnimator valueAnimator) {
                                      PointF point = (PointF)valueAnimator.getAnimatedValue();
                                      view.setTranslationX(point.x);
                                       view.setTranslationY(point.y);
                         }
    });

    设置成功 开启动画  最后监听动画结束时remove这个ImageView

    4.结束语

    写逻辑代码写的久了很多时候就会忘了一般的动画实现,这个动画实现虽然没什么含金量,但是很多项目中都可能会用得到可以直接使用还是很方便的,大神掠过,新接触android动画的还是可以看看的,代码内注释很详细。

    源码在这里   GitHub - jlcclidong/AddCartAniamtion: 仿美团外卖添加动画的三方库

    这个库的主要灵感感谢 

    Android 属性动画(Property Animation) 完全解析 (上) - Hongyang - 博客频道 - CSDN.NET

    把商品添加到购物车的动画效果(贝塞尔曲线) - Android_Study_OK的博客 - 博客频道 - CSDN.NET 

    相关文章

      网友评论

      • d_bert_1992:楼主 你知道多规格时候的动画从弹窗上出来的怎么处理的么?
      • 械勒的时间:艾玛正需要
      • minych:我之前的做法是这样的:假设动画的起始位置是一个抛物线的顶点,两个view之间的距离为dx、dy,那么根据顶点公式y=a(x-h)^2+k(顶点为(h,k)),就可以算出a,在根据x在动画时间内的变化算出y,最后setTranslationX(x)和setTranslationY(y)
      • 捡淑:马克
      • 奋斗的Leo:其实不用这么麻烦的,运动的曲线是一条二阶贝塞尔曲线.
        你可以用PathMeasure或者直接就用PathInterpolator这个动画插值器搞定.
        iam薛定諤:@奋斗的Leo 试过中点和一些其他的点,感觉这样加插值器效果不怎么好,不知道那个点怎么计算,曲线才会自然一点,就没用
        奋斗的Leo:@iam薛定諤 可以试试中点,简单实现的话 (h1 + h2)/2,(w1 + w2)/2
        iam薛定諤:@奋斗的Leo 之前也想这么做来着,但是不知道那个控制点在哪里才看起来最自然
      • 296d6ebc6cd2:有搜到这个吗 https://github.com/captain-miao/ShoppingCartAnimation
        KingofGlory:@颜路 你的库里ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView();这句代码很重要,不然在购物车在Activity里面,商品在Fragment的List里面这种情况就不生效。上面的文章就有这个局限。
        iam薛定諤:@颜路 没搜到啊,回头研究研究

      本文标题:仿美团外卖添加商品的抛物线动画

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