Android把商品添加到购物车的动画效果(贝塞尔曲线)

Android把商品添加到购物车的动画效果(贝塞尔曲线),第1张

概述当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下:

当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下:

实现效果如图:

思路:

确定动画的起终点 在起终点之间使用二次贝塞尔曲线填充起终点之间的点的轨迹 设置属性动画,ValueAnimator插值器,获取中间点的坐标 将执行动画的控件的x、y坐标设为上面得到的中间点坐标 开启属性动画 当动画结束时的 *** 作

难点:

PathMeasure的使用
- getLength()
- boolean getPosTan(float distance,float[] pos,float[] tan) 的理解

涉及到的知识点:

如何获取控件在屏幕中的绝对坐标

//得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标)  int[] parentLocation = new int[2];  rl.getLocationInWindow(parentLocation);

如何使用贝塞尔曲线以及属性动画插值器ValueAnimator
  

 //    四、计算中间动画的插值坐标(贝塞尔曲线)(其实就是用贝塞尔曲线来完成起终点的过程)    //开始绘制贝塞尔曲线    Path path = new Path();    //移动到起始点(贝塞尔曲线的起点)    path.moveto(startX,startY);    //使用二次萨贝尔曲线:注意第一个起始坐标越大,贝塞尔曲线的横向距离就会越大,一般按照下面的式子取即可    path.quadTo((startX + toX) / 2,startY,toX,toY);    //mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标,    // 如果是true,path会形成一个闭环    mPathMeasure = new PathMeasure(path,false);    //★★★属性动画实现(从0到贝塞尔曲线的长度之间进行插值计算,获取中间过程的距离值)    ValueAnimator valueAnimator = ValueAnimator.offloat(0,mPathMeasure.getLength());    valueAnimator.setDuration(1000);    // 匀速线性插值器    valueAnimator.setInterpolator(new linearInterpolator());    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @OverrIDe      public voID onAnimationUpdate(ValueAnimator animation) {        // 当插值计算进行时,获取中间的每个值,        // 这里这个值是中间过程中的曲线长度(下面根据这个值来得出中间点的坐标值)        float value = (float) animation.getAnimatedValue();        // ★★★★★获取当前点坐标封装到mCurrentposition        // boolean getPosTan(float distance,float[] tan) :        // 传入一个距离distance(0<=distance<=getLength()),然后会计算当前距        // 离的坐标点和切线,pos会自动填充上坐标,这个方法很重要。        mPathMeasure.getPosTan(value,mCurrentposition,null);//mCurrentposition此时就是中间距离点的坐标值        // 移动的商品图片(动画图片)的坐标设置为该中间点的坐标        goods.setTranslationX(mCurrentposition[0]);        goods.setTranslationY(mCurrentposition[1]);      }    });//   五、 开始执行动画    valueAnimator.start();

所有代码:

package cn.c.com.bezIErcurveanimater;@R_301_5565@ androID.animation.Animator;@R_301_5565@ androID.animation.ValueAnimator;@R_301_5565@ androID.graphics.Bitmap;@R_301_5565@ androID.graphics.BitmapFactory;@R_301_5565@ androID.graphics.Path;@R_301_5565@ androID.graphics.PathMeasure;@R_301_5565@ androID.os.Bundle;@R_301_5565@ androID.support.v7.app.AppCompatActivity;@R_301_5565@ androID.support.v7.Widget.linearlayoutmanager;@R_301_5565@ androID.support.v7.Widget.RecyclerVIEw;@R_301_5565@ androID.vIEw.LayoutInflater;@R_301_5565@ androID.vIEw.VIEw;@R_301_5565@ androID.vIEw.VIEwGroup;@R_301_5565@ androID.vIEw.animation.linearInterpolator;@R_301_5565@ androID.Widget.ImageVIEw;@R_301_5565@ androID.Widget.relativeLayout;@R_301_5565@ androID.Widget.TextVIEw;@R_301_5565@ java.util.ArrayList;public class MainActivity extends AppCompatActivity {  private RecyclerVIEw mRecyclerVIEw;  private ImageVIEw cart;  private ArrayList<Bitmap> bitmapList = new ArrayList<>();  private relativeLayout rl;  private PathMeasure mPathMeasure;  /**   * 贝塞尔曲线中间过程的点的坐标   */  private float[] mCurrentposition = new float[2];  private TextVIEw count;  private int i = 0;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    initVIEw();    initimg();    MyAdapter myAdapter = new MyAdapter(bitmapList);    mRecyclerVIEw.setAdapter(myAdapter);    mRecyclerVIEw.setLayoutManager(new linearlayoutmanager(MainActivity.this));  }  private voID initimg() {    bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin));    bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin1));    bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin91));  }  private voID initVIEw() {    mRecyclerVIEw = (RecyclerVIEw) findVIEwByID(R.ID.recyclerVIEw);    cart = (ImageVIEw) findVIEwByID(R.ID.cart);    rl = (relativeLayout) findVIEwByID(R.ID.rl);    count = (TextVIEw) findVIEwByID(R.ID.count);  }  class MyAdapter extends RecyclerVIEw.Adapter<MyVH> {    private ArrayList<Bitmap> bitmapList;    public MyAdapter(ArrayList<Bitmap> bitmapList) {      this.bitmapList = bitmapList;    }    @OverrIDe    public MyVH onCreateVIEwHolder(VIEwGroup parent,int vIEwType) {      LayoutInflater inflater = LayoutInflater.from(MainActivity.this);      VIEw itemVIEw = inflater.inflate(R.layout.item,parent,false);      MyVH myVH = new MyVH(itemVIEw);      return myVH;    }    @OverrIDe    public voID onBindVIEwHolder(final MyVH holder,final int position) {      holder.iv.setimageBitmap(bitmapList.get(position));      holder.buy.setonClickListener(new VIEw.OnClickListener() {        @OverrIDe        public voID onClick(VIEw v) {          addCart(holder.iv);        }      });    }    @OverrIDe    public int getItemCount() {      return bitmapList.size();    }  }  /**   * ★★★★★把商品添加到购物车的动画效果★★★★★   * @param iv   */  private voID addCart( ImageVIEw iv) {//   一、创造出执行动画的主题---imagevIEw    //代码new一个imagevIEw,图片资源是上面的imagevIEw的图片    // (这个图片就是执行动画的图片,从开始位置出发,经过一个抛物线(贝塞尔曲线),移动到购物车里)    final ImageVIEw goods = new ImageVIEw(MainActivity.this);    goods.setimageDrawable(iv.getDrawable());    relativeLayout.LayoutParams params = new relativeLayout.LayoutParams(100,100);    rl.addVIEw(goods,params);//    二、计算动画开始/结束点的坐标的准备工作    //得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标)    int[] parentLocation = new int[2];    rl.getLocationInWindow(parentLocation);    //得到商品图片的坐标(用于计算动画开始的坐标)    int startLoc[] = new int[2];    iv.getLocationInWindow(startLoc);    //得到购物车图片的坐标(用于计算动画结束后的坐标)    int endLoc[] = new int[2];    cart.getLocationInWindow(endLoc);//    三、正式开始计算动画开始/结束的坐标    //开始掉落的商品的起始点:商品起始点-父布局起始点+该商品图片的一半    float startX = startLoc[0] - parentLocation[0] + iv.getWIDth() / 2;    float startY = startLoc[1] - parentLocation[1] + iv.getHeight() / 2;    //商品掉落后的终点坐标:购物车起始点-父布局起始点+购物车图片的1/5    float toX = endLoc[0] - parentLocation[0] + cart.getWIDth() / 5;    float toY = endLoc[1] - parentLocation[1];//    四、计算中间动画的插值坐标(贝塞尔曲线)(其实就是用贝塞尔曲线来完成起终点的过程)    //开始绘制贝塞尔曲线    Path path = new Path();    //移动到起始点(贝塞尔曲线的起点)    path.moveto(startX,null);//mCurrentposition此时就是中间距离点的坐标值        // 移动的商品图片(动画图片)的坐标设置为该中间点的坐标        goods.setTranslationX(mCurrentposition[0]);        goods.setTranslationY(mCurrentposition[1]);      }    });//   五、 开始执行动画    valueAnimator.start();//   六、动画结束后的处理    valueAnimator.addListener(new Animator.AnimatorListener() {      @OverrIDe      public voID onAnimationStart(Animator animation) {      }      //当动画结束后:      @OverrIDe      public voID onAnimationEnd(Animator animation) {        // 购物车的数量加1        i++;        count.setText(String.valueOf(i));        // 把移动的图片imagevIEw从父布局里移除        rl.removeVIEw(goods);      }      @OverrIDe      public voID onAnimationCancel(Animator animation) {      }      @OverrIDe      public voID onAnimationRepeat(Animator animation) {      }    });  }  class MyVH extends RecyclerVIEw.VIEwHolder {    private ImageVIEw iv;    private TextVIEw buy;    public MyVH(VIEw itemVIEw) {      super(itemVIEw);      iv = (ImageVIEw) itemVIEw.findVIEwByID(R.ID.iv);      buy = (TextVIEw) itemVIEw.findVIEwByID(R.ID.buy);    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android把商品添加到购物车的动画效果(贝塞尔曲线)全部内容,希望文章能够帮你解决Android把商品添加到购物车的动画效果(贝塞尔曲线)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1147823.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存