手记

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

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动画的还是可以看看的,代码内注释很详细。

源码在这里:  http://www.apkbus.com/thread-588789-1-1.html

原文链接:http://www.apkbus.com/blog-865196-76655.html

0人推荐
随时随地看视频
慕课网APP